/*
 * @(#)$Id$
 *
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2001-2003 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);
	handler.init();
	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 (baseName != null) {
		    baseName = Util.noExtName(baseName);
		    transletBaseName = Util.toJavaName(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;
    }
}
