/*
 * @(#)$Id$
 *
 * 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/>.
 *
 * @author G. Todd Miller 
 * @author Morten Jorgensen
 * @author Santiago Pericas-Geertsen
 *
 */

package org.apache.xalan.xsltc.trax;

import java.io.File;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.Reader;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.ByteArrayInputStream;
import java.io.FilenameFilter;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.Vector;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Enumeration;
import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;

import javax.xml.transform.*;
import javax.xml.transform.sax.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.*;
import org.w3c.dom.Document;

import org.apache.xalan.xsltc.Translet;
import org.apache.xalan.xsltc.runtime.AbstractTranslet;

import org.apache.xalan.xsltc.compiler.XSLTC;
import org.apache.xalan.xsltc.compiler.SourceLoader;
import org.apache.xalan.xsltc.compiler.CompilerException;
import org.apache.xalan.xsltc.compiler.util.ErrorMsg;

/**
 * Implementation of a JAXP1.1 TransformerFactory for Translets.
 */
public class TransformerFactoryImpl
    extends SAXTransformerFactory implements SourceLoader, ErrorListener 
{
    /**
     * This error listener is used only for this factory and is not passed to
     * the Templates or Transformer objects that we create.
     */
    private ErrorListener _errorListener = this; 

    /**
     * This URIResolver is passed to all created Templates and Transformers
     */
    private URIResolver _uriResolver = null;

    /** 
     * As Gregor Samsa awoke one morning from uneasy dreams he found himself
     * transformed in his bed into a gigantic insect. He was lying on his hard,
     * as it were armour plated, back, and if he lifted his head a little he
     * could see his big, brown belly divided into stiff, arched segments, on
     * top of which the bed quilt could hardly keep in position and was about
     * to slide off completely. His numerous legs, which were pitifully thin
     * compared to the rest of his bulk, waved helplessly before his eyes.
     * "What has happened to me?", he thought. It was no dream....
     */
    protected static String DEFAULT_TRANSLET_NAME = "GregorSamsa";
    
    /**
     * The class name of the translet
     */
    private String _transletName = DEFAULT_TRANSLET_NAME;
    
    /**
     * The destination directory for the translet
     */
    private String _destinationDirectory = null;
    
    /**
     * The package name prefix for all generated translet classes
     */
    private String _packageName = null;
    
    /**
     * The jar file name which the translet classes are packaged into
     */
    private String _jarFileName = null;

    /**
     * This Hashtable is used to store parameters for locating
     * <?xml-stylesheet ...?> processing instructions in XML docs.
     */
    private Hashtable _piParams = null;


    /**
     * Use a thread local variable to store a copy of an XML Reader.
     */
    static ThreadLocal _xmlReader = new ThreadLocal();

    /**
     * The above hashtable stores objects of this class.
     */
    private static class PIParamWrapper {
	public String _media = null;
	public String _title = null;
	public String _charset = null;
	
	public PIParamWrapper(String media, String title, String charset) {
	    _media = media;
	    _title = title;
	    _charset = charset;
	}
    }

    /**
     * Set to <code>true</code> when debugging is enabled.
     */
    private boolean _debug = false;

    /**
     * Set to <code>true</code> when templates are inlined.
     */
    private boolean _enableInlining = false;
    
    /**
     * Set to <code>true</code> when we want to generate 
     * translet classes from the stylesheet.
     */
    private boolean _generateTranslet = false;
    
    /**
     * If this is set to <code>true</code>, we attempt to use translet classes for 
     * transformation if possible without compiling the stylesheet. The translet class
     * is only used if its timestamp is newer than the timestamp of the stylesheet.
     */
    private boolean _autoTranslet = false;

    /**
     * Number of indent spaces when indentation is turned on.
     */
    private int _indentNumber = -1;

    /**
     * A reference to a SAXParserFactory.
     */
    private SAXParserFactory _parserFactory = null;

    /**
     * javax.xml.transform.sax.TransformerFactory implementation.
     * Contains nothing yet
     */
    public TransformerFactoryImpl() {
    }

    /**
     * javax.xml.transform.sax.TransformerFactory implementation.
     * Set the error event listener for the TransformerFactory, which is used
     * for the processing of transformation instructions, and not for the
     * transformation itself.
     *
     * @param listener The error listener to use with the TransformerFactory
     * @throws IllegalArgumentException
     */
    public void setErrorListener(ErrorListener listener) 
	throws IllegalArgumentException 
    {
	if (listener == null) {
	    ErrorMsg err = new ErrorMsg(ErrorMsg.ERROR_LISTENER_NULL_ERR,
					"TransformerFactory");
            throw new IllegalArgumentException(err.toString());
	}
	_errorListener = listener;
    }

    /**
     * javax.xml.transform.sax.TransformerFactory implementation.
     * Get the error event handler for the TransformerFactory.
     *
     * @return The error listener used with the TransformerFactory
     */
    public ErrorListener getErrorListener() { 
	return _errorListener;
    }

    /**
     * javax.xml.transform.sax.TransformerFactory implementation.
     * Returns the value set for a TransformerFactory attribute
     *
     * @param name The attribute name
     * @return An object representing the attribute value
     * @throws IllegalArgumentException
     */
    public Object getAttribute(String name) 
	throws IllegalArgumentException 
    { 
	// Return value for attribute 'translet-name'
	if (name.equals("translet-name")) {
	    return _transletName;
	}
	else if (name.equals("generate-translet")) {
	    return new Boolean(_generateTranslet);
	}
	else if (name.equals("auto-translet")) {
	    return new Boolean(_autoTranslet);
	}

	// Throw an exception for all other attributes
	ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_INVALID_ATTR_ERR, name);
	throw new IllegalArgumentException(err.toString());
    }

    /**
     * javax.xml.transform.sax.TransformerFactory implementation.
     * Sets the value for a TransformerFactory attribute.
     *
     * @param name The attribute name
     * @param value An object representing the attribute value
     * @throws IllegalArgumentException
     */
    public void setAttribute(String name, Object value) 
	throws IllegalArgumentException 
    { 
	// Set the default translet name (ie. class name), which will be used
	// for translets that cannot be given a name from their system-id.
	if (name.equals("translet-name") && value instanceof String) {
	    _transletName = (String) value;	      
	    return;
	}
	else if (name.equals("destination-directory") && value instanceof String) {
	    _destinationDirectory = (String) value;
	    return;
	}
	else if (name.equals("package-name") && value instanceof String) {
	    _packageName = (String) value;
	    return;
	}
	else if (name.equals("jar-name") && value instanceof String) {
	    _jarFileName = (String) value;
	    return;
	}
	else if (name.equals("generate-translet")) {
	    if (value instanceof Boolean) {
		_generateTranslet = ((Boolean) value).booleanValue();
		return;
	    }
	    else if (value instanceof String) {
		_generateTranslet = ((String) value).equalsIgnoreCase("true");
		return;
	    }
	}
	else if (name.equals("auto-translet")) {
	    if (value instanceof Boolean) {
		_autoTranslet = ((Boolean) value).booleanValue();
		return;
	    }
	    else if (value instanceof String) {
		_autoTranslet = ((String) value).equalsIgnoreCase("true");
		return;
	    }
	}
	else if (name.equals("debug")) {
	    if (value instanceof Boolean) {
		_debug = ((Boolean) value).booleanValue();
		return;
	    }
	    else if (value instanceof String) {
		_debug = ((String) value).equalsIgnoreCase("true");
		return;
	    }
	}
	else if (name.equals("enable-inlining")) {
	    if (value instanceof Boolean) {
		_enableInlining = ((Boolean) value).booleanValue();
		return;
	    }
	    else if (value instanceof String) {
		_enableInlining = ((String) value).equalsIgnoreCase("true");
		return;
	    }
	}
	else if (name.equals("indent-number")) {
	    if (value instanceof String) {
		try {
		    _indentNumber = Integer.parseInt((String) value);
		    return;
		}
		catch (NumberFormatException e) {
		    // Falls through
		}
	    }
	    else if (value instanceof Integer) {
		_indentNumber = ((Integer) value).intValue();
		return;
	    }
	}

	// Throw an exception for all other attributes
	final ErrorMsg err 
	    = new ErrorMsg(ErrorMsg.JAXP_INVALID_ATTR_ERR, name);
	throw new IllegalArgumentException(err.toString());
    }

    /**
     * javax.xml.transform.sax.TransformerFactory implementation.
     * Look up the value of a feature (to see if it is supported).
     * This method must be updated as the various methods and features of this
     * class are implemented.
     *
     * @param name The feature name
     * @return 'true' if feature is supported, 'false' if not
     */
    public boolean getFeature(String name) { 
	// All supported features should be listed here
	String[] features = {
	    DOMSource.FEATURE,
	    DOMResult.FEATURE,
	    SAXSource.FEATURE,
	    SAXResult.FEATURE,
	    StreamSource.FEATURE,
	    StreamResult.FEATURE
	};

	// Inefficient, but array is small
	for (int i =0; i < features.length; i++) {
	    if (name.equals(features[i])) {
		return true;
	    }
	}
	// Feature not supported
	return false;
    }

    /**
     * javax.xml.transform.sax.TransformerFactory implementation.
     * Get the object that is used by default during the transformation to
     * resolve URIs used in document(), xsl:import, or xsl:include.
     *
     * @return The URLResolver used for this TransformerFactory and all
     * Templates and Transformer objects created using this factory
     */    
    public URIResolver getURIResolver() {
	return _uriResolver;
    } 

    /**
     * javax.xml.transform.sax.TransformerFactory implementation.
     * Set the object that is used by default during the transformation to
     * resolve URIs used in document(), xsl:import, or xsl:include. Note that
     * this does not affect Templates and Transformers that are already
     * created with this factory.
     *
     * @param resolver The URLResolver used for this TransformerFactory and all
     * Templates and Transformer objects created using this factory
     */    
    public void setURIResolver(URIResolver resolver) {
	_uriResolver = resolver;
    }

    /**
     * javax.xml.transform.sax.TransformerFactory implementation.
     * Get the stylesheet specification(s) associated via the xml-stylesheet
     * processing instruction (see http://www.w3.org/TR/xml-stylesheet/) with
     * the document document specified in the source parameter, and that match
     * the given criteria.
     *
     * @param source The XML source document.
     * @param media The media attribute to be matched. May be null, in which
     * case the prefered templates will be used (i.e. alternate = no).
     * @param title The value of the title attribute to match. May be null.
     * @param charset The value of the charset attribute to match. May be null.
     * @return A Source object suitable for passing to the TransformerFactory.
     * @throws TransformerConfigurationException
     */
    public Source getAssociatedStylesheet(Source source, String media,
					  String title, String charset)
	throws TransformerConfigurationException 
    {
	// First create a hashtable that maps Source refs. to parameters
	if (_piParams == null) {
	    _piParams = new Hashtable();
	}
	// Store the parameters for this Source in the Hashtable
	_piParams.put(source, new PIParamWrapper(media, title, charset));
	// Return the same Source - we'll locate the stylesheet later
	return source;
    }

    /**
     * javax.xml.transform.sax.TransformerFactory implementation.
     * Create a Transformer object that copies the input document to the result.
     *
     * @return A Transformer object that simply copies the source to the result.
     * @throws TransformerConfigurationException
     */    
    public Transformer newTransformer()
	throws TransformerConfigurationException 
    { 
	TransformerImpl result = new TransformerImpl(new Properties(), 
	    _indentNumber, this);
	if (_uriResolver != null) {
	    result.setURIResolver(_uriResolver);
	}
	return result;
    }

    /**
     * javax.xml.transform.sax.TransformerFactory implementation.
     * Process the Source into a Templates object, which is a a compiled
     * representation of the source. Note that this method should not be
     * used with XSLTC, as the time-consuming compilation is done for each
     * and every transformation.
     *
     * @return A Templates object that can be used to create Transformers.
     * @throws TransformerConfigurationException
     */
    public Transformer newTransformer(Source source) throws
	TransformerConfigurationException 
    {
	final Templates templates = newTemplates(source);
	final Transformer transformer = templates.newTransformer();
	if (_uriResolver != null) {
	    transformer.setURIResolver(_uriResolver);
	}
	return(transformer);
    }

    /**
     * Pass warning messages from the compiler to the error listener
     */
    private void passWarningsToListener(Vector messages) 
	throws TransformerException 
    {
	if (_errorListener == null || messages == null) {
	    return;
	}
	// Pass messages to listener, one by one
	final int count = messages.size();
	for (int pos = 0; pos < count; pos++) {
	    String message = messages.elementAt(pos).toString();
	    _errorListener.error(
		new TransformerConfigurationException(message));
	}
    }

    /**
     * Pass error messages from the compiler to the error listener
     */
    private void passErrorsToListener(Vector messages) {
	try {
	    if (_errorListener == null || messages == null) {
		return;
	    }
	    // Pass messages to listener, one by one
	    final int count = messages.size();
	    for (int pos = 0; pos < count; pos++) {
		String message = messages.elementAt(pos).toString();
		_errorListener.error(new TransformerException(message));
	    }
	}
	catch (TransformerException e) {
	    // nada
	}
    }

    /**
     * javax.xml.transform.sax.TransformerFactory implementation.
     * Process the Source into a Templates object, which is a a compiled
     * representation of the source.
     *
     * @param stylesheet The input stylesheet - DOMSource not supported!!!
     * @return A Templates object that can be used to create Transformers.
     * @throws TransformerConfigurationException
     */
    public Templates newTemplates(Source source)
	throws TransformerConfigurationException 
    {
	// If _autoTranslet is true, we will try to load the bytecodes
	// from the translet classes without compiling the stylesheet.
	if (_autoTranslet)  {
	    byte[][] bytecodes = null;
	    String transletClassName = getTransletClassName(source);
	    
	    if (_jarFileName != null)
	    	bytecodes = getBytecodesFromJar(source, transletClassName);
	    else
	    	bytecodes = getBytecodesFromClasses(source, transletClassName);	    
	  
	    if (bytecodes != null) {
	    	if (_debug) {
	      	    if (_jarFileName != null)
	        	System.err.println(new ErrorMsg(
	            	    ErrorMsg.TRANSFORM_WITH_JAR_STR, transletClassName, _jarFileName));
	            else
	            	System.err.println(new ErrorMsg(
	            	    ErrorMsg.TRANSFORM_WITH_TRANSLET_STR, transletClassName));
	    	}

	    	// Reset the per-session attributes to their default values
	    	// after each newTemplates() call.
	    	resetTransientAttributes();
	    
	    	return new TemplatesImpl(bytecodes, transletClassName, null, _indentNumber, this);	    
	    }
	}
	
	// Create and initialize a stylesheet compiler
	final XSLTC xsltc = new XSLTC();
	if (_debug) xsltc.setDebug(true);
	if (_enableInlining) xsltc.setTemplateInlining(true);
	xsltc.init();

	// Set a document loader (for xsl:include/import) if defined
	if (_uriResolver != null) {
	    xsltc.setSourceLoader(this);
	}

	// Pass parameters to the Parser to make sure it locates the correct
	// <?xml-stylesheet ...?> PI in an XML input document
	if ((_piParams != null) && (_piParams.get(source) != null)) {
	    // Get the parameters for this Source object
	    PIParamWrapper p = (PIParamWrapper)_piParams.get(source);
	    // Pass them on to the compiler (which will pass then to the parser)
	    if (p != null) {
		xsltc.setPIParameters(p._media, p._title, p._charset);
	    }
	}

	// Set the attributes for translet generation
	int outputType = XSLTC.BYTEARRAY_OUTPUT;
	if (_generateTranslet || _autoTranslet) {
	    // Set the translet name
	    if (!_transletName.equals(DEFAULT_TRANSLET_NAME))
	        xsltc.setClassName(_transletName);
	  
	    if (_destinationDirectory != null)
	    	xsltc.setDestDirectory(_destinationDirectory);
	    else {
	    	String xslName = getStylesheetFileName(source);
	    	if (xslName != null) {
	      	    File xslFile = new File(xslName);
	            String xslDir = xslFile.getParent();
	    
	      	    if (xslDir != null)
	                xsltc.setDestDirectory(xslDir);
	    	}
	    }
	  
	    if (_packageName != null)
	        xsltc.setPackageName(_packageName);
	
	    if (_jarFileName != null) {
	    	xsltc.setJarFileName(_jarFileName);
	    	outputType = XSLTC.BYTEARRAY_AND_JAR_OUTPUT;
	    }
	    else
	    	outputType = XSLTC.BYTEARRAY_AND_FILE_OUTPUT;
	}

	// Compile the stylesheet
	final InputSource input = Util.getInputSource(xsltc, source);
	byte[][] bytecodes = xsltc.compile(null, input, outputType);
	final String transletName = xsltc.getClassName();

	// Output to the jar file if the jar file name is set.
	if ((_generateTranslet || _autoTranslet)
	   	&& bytecodes != null && _jarFileName != null) {
	    try {
	    	xsltc.outputToJar();
	    }
	    catch (java.io.IOException e) { }
	}

	// Reset the per-session attributes to their default values
	// after each newTemplates() call.
	resetTransientAttributes();

	// Pass compiler warnings to the error listener
	if (_errorListener != this) {
	    try {
		passWarningsToListener(xsltc.getWarnings());
	    }
	    catch (TransformerException e) {
		throw new TransformerConfigurationException(e);
	    }
	}
	else {
	    xsltc.printWarnings();
	}

	// Check that the transformation went well before returning
	if (bytecodes == null) {
	    // Pass compiler errors to the error listener
	    if (_errorListener != null) {
		passErrorsToListener(xsltc.getErrors());
	    }
	    else {
		xsltc.printErrors();
	    }
	    ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_COMPILE_ERR);
	    throw new TransformerConfigurationException(err.toString());
	}

	return new TemplatesImpl(bytecodes, transletName, 
	    xsltc.getOutputProperties(), _indentNumber, this);
    }

    /**
     * javax.xml.transform.sax.SAXTransformerFactory implementation.
     * Get a TemplatesHandler object that can process SAX ContentHandler
     * events into a Templates object.
     *
     * @return A TemplatesHandler object that can handle SAX events
     * @throws TransformerConfigurationException
     */
    public TemplatesHandler newTemplatesHandler() 
	throws TransformerConfigurationException 
    { 
	final TemplatesHandlerImpl handler = 
	    new TemplatesHandlerImpl(_indentNumber, this);
	if (_uriResolver != null) {
	    handler.setURIResolver(_uriResolver);
	}
	return handler;
    }

    /**
     * javax.xml.transform.sax.SAXTransformerFactory implementation.
     * Get a TransformerHandler object that can process SAX ContentHandler
     * events into a Result. This method will return a pure copy transformer.
     *
     * @return A TransformerHandler object that can handle SAX events
     * @throws TransformerConfigurationException
     */
    public TransformerHandler newTransformerHandler() 
	throws TransformerConfigurationException 
    {
	final Transformer transformer = newTransformer();
	if (_uriResolver != null) {
	    transformer.setURIResolver(_uriResolver);
	}
	return new TransformerHandlerImpl((TransformerImpl) transformer);
    }

    /**
     * javax.xml.transform.sax.SAXTransformerFactory implementation.
     * Get a TransformerHandler object that can process SAX ContentHandler
     * events into a Result, based on the transformation instructions
     * specified by the argument.
     *
     * @param src The source of the transformation instructions.
     * @return A TransformerHandler object that can handle SAX events
     * @throws TransformerConfigurationException
     */
    public TransformerHandler newTransformerHandler(Source src) 
	throws TransformerConfigurationException 
    { 
	final Transformer transformer = newTransformer(src);
	if (_uriResolver != null) {
	    transformer.setURIResolver(_uriResolver);
	}
	return new TransformerHandlerImpl((TransformerImpl) transformer);
    }

    /**
     * javax.xml.transform.sax.SAXTransformerFactory implementation.
     * Get a TransformerHandler object that can process SAX ContentHandler
     * events into a Result, based on the transformation instructions
     * specified by the argument.
     *
     * @param templates Represents a pre-processed stylesheet
     * @return A TransformerHandler object that can handle SAX events
     * @throws TransformerConfigurationException
     */    
    public TransformerHandler newTransformerHandler(Templates templates) 
	throws TransformerConfigurationException  
    {
	final Transformer transformer = templates.newTransformer();
	final TransformerImpl internal = (TransformerImpl)transformer;
	return new TransformerHandlerImpl(internal);
    }

    /**
     * javax.xml.transform.sax.SAXTransformerFactory implementation.
     * Create an XMLFilter that uses the given source as the
     * transformation instructions.
     *
     * @param src The source of the transformation instructions.
     * @return An XMLFilter object, or null if this feature is not supported.
     * @throws TransformerConfigurationException
     */
    public XMLFilter newXMLFilter(Source src) 
	throws TransformerConfigurationException 
    {
	Templates templates = newTemplates(src);
	if (templates == null) return null; 
	return newXMLFilter(templates);
    }

    /**
     * javax.xml.transform.sax.SAXTransformerFactory implementation.
     * Create an XMLFilter that uses the given source as the
     * transformation instructions.
     *
     * @param src The source of the transformation instructions.
     * @return An XMLFilter object, or null if this feature is not supported.
     * @throws TransformerConfigurationException
     */
    public XMLFilter newXMLFilter(Templates templates) 
	throws TransformerConfigurationException 
    {
	try {
      	    return new org.apache.xalan.xsltc.trax.TrAXFilter(templates);
    	}
	catch (TransformerConfigurationException e1) {
      	    if (_errorListener != null) {
                try {
          	    _errorListener.fatalError(e1);
          	    return null;
        	}
		catch (TransformerException e2) {
          	    new TransformerConfigurationException(e2);
        	}
      	    }
      	    throw e1;
    	}
    }

    /**
     * Receive notification of a recoverable error. 
     * The transformer must continue to provide normal parsing events after
     * invoking this method. It should still be possible for the application
     * to process the document through to the end.
     *
     * @param exception The warning information encapsulated in a transformer 
     * exception.
     * @throws TransformerException if the application chooses to discontinue
     * the transformation (always does in our case).
     */
    public void error(TransformerException e)
	throws TransformerException 
    {
	Throwable wrapped = e.getException();
        if (wrapped != null) {
            System.err.println(new ErrorMsg(ErrorMsg.ERROR_PLUS_WRAPPED_MSG,
                                            e.getMessageAndLocation(),
                                            wrapped.getMessage()));
        } else {
            System.err.println(new ErrorMsg(ErrorMsg.ERROR_MSG,
                                            e.getMessageAndLocation()));
	}
	throw e; 	
    }

    /**
     * Receive notification of a non-recoverable error. 
     * The application must assume that the transformation cannot continue
     * after the Transformer has invoked this method, and should continue
     * (if at all) only to collect addition error messages. In fact,
     * Transformers are free to stop reporting events once this method has
     * been invoked.
     *
     * @param exception The warning information encapsulated in a transformer
     * exception.
     * @throws TransformerException if the application chooses to discontinue
     * the transformation (always does in our case).
     */
    public void fatalError(TransformerException e)
	throws TransformerException 
    {
	Throwable wrapped = e.getException();
        if (wrapped != null) {
            System.err.println(new ErrorMsg(ErrorMsg.FATAL_ERR_PLUS_WRAPPED_MSG,
                                            e.getMessageAndLocation(),
                                            wrapped.getMessage()));
        } else {
            System.err.println(new ErrorMsg(ErrorMsg.FATAL_ERR_MSG,
                                            e.getMessageAndLocation()));
        }
	throw e;
    }

    /**
     * Receive notification of a warning.
     * Transformers can use this method to report conditions that are not
     * errors or fatal errors. The default behaviour is to take no action.
     * After invoking this method, the Transformer must continue with the
     * transformation. It should still be possible for the application to
     * process the document through to the end.
     *
     * @param exception The warning information encapsulated in a transformer
     * exception.
     * @throws TransformerException if the application chooses to discontinue
     * the transformation (never does in our case).
     */
    public void warning(TransformerException e)
	throws TransformerException 
    {
	Throwable wrapped = e.getException();
	if (wrapped != null) {
            System.err.println(new ErrorMsg(ErrorMsg.WARNING_PLUS_WRAPPED_MSG,
                                            e.getMessageAndLocation(),
                                            wrapped.getMessage()));
	} else {
            System.err.println(new ErrorMsg(ErrorMsg.WARNING_MSG,
                                            e.getMessageAndLocation()));
        }
    }

    /**
     * This method implements XSLTC's SourceLoader interface. It is used to
     * glue a TrAX URIResolver to the XSLTC compiler's Input and Import classes.
     *
     * @param href The URI of the document to load
     * @param context The URI of the currently loaded document
     * @param xsltc The compiler that resuests the document
     * @return An InputSource with the loaded document
     */
    public InputSource loadSource(String href, String context, XSLTC xsltc) {
	try {
	    if (_uriResolver != null) {
		final Source source = _uriResolver.resolve(href, context);
		if (source != null) {
		    return Util.getInputSource(xsltc, source);
		}
	    }
	}
	catch (TransformerException e) {
	    // Falls through
	}
	return null;
    }

    /**
     * This method is synchronized to allow instances of this class to 
     * be shared among threads. A tranformer object will call this 
     * method to get an XMLReader. A different instance of an XMLReader
     * is returned/cached for each thread.
     */
    public synchronized XMLReader getXMLReader() throws Exception {
	// First check if factory is instantiated
	if (_parserFactory == null) {
	    _parserFactory = SAXParserFactory.newInstance();
	    _parserFactory.setNamespaceAware(true);
	}
	XMLReader result = (XMLReader) _xmlReader.get();
	if (result == null) {
	    _xmlReader.set(
		result = _parserFactory.newSAXParser().getXMLReader());
	}
	return result;
    }
    
    /**
     * Reset the per-session attributes to their default values
     */
    private void resetTransientAttributes() {
	_transletName = DEFAULT_TRANSLET_NAME;
	_destinationDirectory = null;
	_packageName = null;
	_jarFileName = null;    
    }
        
    /**
     * Load the translet classes from local .class files and return
     * the bytecode array.
     *
     * @param source The xsl source
     * @param fullClassName The full name of the translet
     * @return The bytecode array
     */
    private byte[][] getBytecodesFromClasses(Source source, String fullClassName)
    {
    	if (fullClassName == null)
    	    return null;
    	  
    	String xslFileName = getStylesheetFileName(source);
    	File xslFile = null;
    	if (xslFileName != null)
    	    xslFile = new File(xslFileName);
    	
    	// Find the base name of the translet
    	final String transletName;
    	int lastDotIndex = fullClassName.lastIndexOf('.');
    	if (lastDotIndex > 0)
    	    transletName = fullClassName.substring(lastDotIndex+1);
    	else
    	    transletName = fullClassName;
    	    	
    	// Construct the path name for the translet class file
    	String transletPath = fullClassName.replace('.', '/');
    	if (_destinationDirectory != null) {
    	    transletPath = _destinationDirectory + "/" + transletPath + ".class";
    	}
    	else {
    	    if (xslFile != null && xslFile.getParent() != null)
    	    	transletPath = xslFile.getParent() + "/" + transletPath + ".class";
    	    else
    	    	transletPath = transletPath + ".class";
    	}
    	    	    	
    	// Return null if the translet class file does not exist.
    	File transletFile = new File(transletPath);
    	if (!transletFile.exists())
    	    return null;
    	    	  
    	// Compare the timestamps of the translet and the xsl file.
    	// If the translet is older than the xsl file, return null 
    	// so that the xsl file is used for the transformation and
    	// the translet is regenerated.
    	if (xslFile != null && xslFile.exists()) {
    	    long xslTimestamp = xslFile.lastModified();
    	    long transletTimestamp = transletFile.lastModified();
    	    if (transletTimestamp < xslTimestamp)
    	    	return null;
    	}
    	
    	// Load the translet into a bytecode array.
    	Vector bytecodes = new Vector();
    	int fileLength = (int)transletFile.length();
    	if (fileLength > 0) {
    	    FileInputStream input = null;
    	    try {
    	    	input = new FileInputStream(transletFile);
    	    }
    	    catch (FileNotFoundException e) {
    	    	return null;
    	    }
    	  
    	    byte[] bytes = new byte[fileLength];
    	    try {
	    	readFromInputStream(bytes, input, fileLength);
	    	input.close();
	    }
	    catch (IOException e) {
    	    	return null;
    	    }
    	  
    	    bytecodes.addElement(bytes);
    	}
    	else
    	    return null;
    	
    	// Find the parent directory of the translet.
    	String transletParentDir = transletFile.getParent();
    	if (transletParentDir == null)
    	    transletParentDir = System.getProperty("user.dir");
    	  
    	File transletParentFile = new File(transletParentDir);
    	
    	// Find all the auxiliary files which have a name pattern of "transletClass$nnn.class".
    	final String transletAuxPrefix = transletName + "$";
    	File[] auxfiles = transletParentFile.listFiles(new FilenameFilter() {
        	public boolean accept(File dir, String name)
    		{
    		    return (name.endsWith(".class") && name.startsWith(transletAuxPrefix));	
    		}
    	      });
    	
    	// Load the auxiliary class files and add them to the bytecode array.
    	for (int i = 0; i < auxfiles.length; i++)
    	{
    	    File auxfile = auxfiles[i];
    	    int auxlength = (int)auxfile.length();
    	    if (auxlength > 0) {
    	    	FileInputStream auxinput = null;
    	    	try {
    	      	    auxinput = new FileInputStream(auxfile);
    	    	}
    	    	catch (FileNotFoundException e) {
    	      	    continue;
    	    	}
    	  
    	    	byte[] bytes = new byte[auxlength];
    	    
    	    	try {
    	      	    readFromInputStream(bytes, auxinput, auxlength);
    	      	    auxinput.close();
    	    	}
    	    	catch (IOException e) {
    	      	    continue;
    	    	}
    	    
    	    	bytecodes.addElement(bytes);   	    
    	    }
    	}
    	
    	// Convert the Vector of byte[] to byte[][].
    	final int count = bytecodes.size();
    	if ( count > 0) {
    	    final byte[][] result = new byte[count][1];
    	    for (int i = 0; i < count; i++) {
    	    	result[i] = (byte[])bytecodes.elementAt(i);
    	    }
    	  
    	    return result;
    	}
    	else
    	    return null;
    }
    
    /**
     * Load the translet classes from the jar file and return the bytecode.
     *
     * @param source The xsl source
     * @param fullClassName The full name of the translet
     * @return The bytecode array
     */
    private byte[][] getBytecodesFromJar(Source source, String fullClassName)
    {
    	String xslFileName = getStylesheetFileName(source);
    	File xslFile = null;
    	if (xslFileName != null)
    	    xslFile = new File(xslFileName);
      
      	// Construct the path for the jar file
      	String jarPath = null;
      	if (_destinationDirectory != null)
            jarPath = _destinationDirectory + "/" + _jarFileName;
      	else {
      	    if (xslFile != null && xslFile.getParent() != null)
    	    	jarPath = xslFile.getParent() + "/" + _jarFileName;
    	    else
    	    	jarPath = _jarFileName;
    	}
            
      	// Return null if the jar file does not exist.
      	File file = new File(jarPath);
      	if (!file.exists())
            return null;

     	// Compare the timestamps of the jar file and the xsl file. Return null
     	// if the xsl file is newer than the jar file.
    	if (xslFile != null && xslFile.exists()) {
    	    long xslTimestamp = xslFile.lastModified();
    	    long transletTimestamp = file.lastModified();
    	    if (transletTimestamp < xslTimestamp)
    	        return null;
    	}
      
      	// Create a ZipFile object for the jar file
      	ZipFile jarFile = null;
      	try {
            jarFile = new ZipFile(file);
      	}
      	catch (IOException e) {
            return null;
      	}
      
      	String transletPath = fullClassName.replace('.', '/');
      	String transletAuxPrefix = transletPath + "$";
      	String transletFullName = transletPath + ".class";
      
      	Vector bytecodes = new Vector();      
      
      	// Iterate through all entries in the jar file to find the 
      	// translet and auxiliary classes.
      	Enumeration entries = jarFile.entries();
      	while (entries.hasMoreElements())
      	{
            ZipEntry entry = (ZipEntry)entries.nextElement();
            String entryName = entry.getName();
            if (entry.getSize() > 0 && 
            	  (entryName.equals(transletFullName) ||
              	  (entryName.endsWith(".class") && 
              	      entryName.startsWith(transletAuxPrefix))))
            {
            	try {
              	    InputStream input = jarFile.getInputStream(entry);
              	    int size = (int)entry.getSize();
              	    byte[] bytes = new byte[size];
              	    readFromInputStream(bytes, input, size);
              	    input.close();
              	    bytecodes.addElement(bytes);
            	}
            	catch (IOException e) {
              	    return null;
            	}          
            }
      	}
      
        // Convert the Vector of byte[] to byte[][].
    	final int count = bytecodes.size();
    	if (count > 0) {
    	    final byte[][] result = new byte[count][1];
    	    for (int i = 0; i < count; i++) {
    	    	result[i] = (byte[])bytecodes.elementAt(i);
    	    }
    	  
    	    return result;
    	}
    	else
    	    return null;
    }
    
    /**
     * Read a given number of bytes from the InputStream into a byte array.
     *
     * @param bytes The byte array to store the input content.
     * @param input The input stream.
     * @param size The number of bytes to read.
     */
    private void readFromInputStream(byte[] bytes, InputStream input, int size)
      	throws IOException
    {
      int n = 0;
      int offset = 0;
      int length = size;
      while (length > 0 && (n = input.read(bytes, offset, length)) > 0) {
          offset = offset + n;
          length = length - n;
      }    
    }

    /**
     * Return the fully qualified class name of the translet
     *
     * @param source The Source
     * @return The full name of the translet class
     */
    private String getTransletClassName(Source source)
    {      
        String transletBaseName = null;
        if (!_transletName.equals(DEFAULT_TRANSLET_NAME))
            transletBaseName = _transletName;
      	else {
            String systemId = source.getSystemId();
            if (systemId != null) {
          	String baseName = Util.baseName(systemId);
                if (baseName != null)
            	    transletBaseName = Util.noExtName(baseName);
            }
      	}
      
        if (transletBaseName == null)
            transletBaseName = DEFAULT_TRANSLET_NAME;
        
        if (_packageName != null)
            return _packageName + "." + transletBaseName;
        else
            return transletBaseName;
    }
        
    /**
     *  Return the local file name from the systemId of the Source object
     *
     * @param source The Source
     * @return The file name in the local filesystem, or null if the
     * systemId does not represent a local file.
     */
    private String getStylesheetFileName(Source source)
    {
    	String systemId = source.getSystemId();
      	if (systemId != null) {
            File file = new File(systemId);
            if (file.exists())
                return systemId;
            else {
              	URL url = null;
          	try {
            	    url = new URL(systemId);
          	}
          	catch (MalformedURLException e) {
            	    return null;
          	}
          
          	if ("file".equals(url.getProtocol()))
            	    return url.getFile();
          	else
            	    return null;
            }
      	}
      	else
            return null;
    }
}
