/*
 * @(#)$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.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Vector;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.ParserConfigurationException;

import javax.xml.transform.ErrorListener;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TemplatesHandler;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.xalan.processor.StylesheetPIHandler;
import org.apache.xalan.processor.StopParseException;

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

import org.apache.xml.utils.ObjectFactory;

import org.xml.sax.InputSource;
import org.xml.sax.XMLFilter;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

/**
 * Implementation of a JAXP1.1 TransformerFactory for Translets.
 */
public class TransformerFactoryImpl
    extends SAXTransformerFactory implements SourceLoader, ErrorListener 
{
    // Public constants for attributes supported by the XSLTC TransformerFactory.
    public final static String TRANSLET_NAME = "translet-name";
    public final static String DESTINATION_DIRECTORY = "destination-directory";
    public final static String PACKAGE_NAME = "package-name";
    public final static String JAR_NAME = "jar-name";
    public final static String GENERATE_TRANSLET = "generate-translet";
    public final static String AUTO_TRANSLET = "auto-translet";
    public final static String USE_CLASSPATH = "use-classpath";
    public final static String DEBUG = "debug";
    public final static String ENABLE_INLINING = "enable-inlining";
    public final static String INDENT_NUMBER = "indent-number";
        
    /**
     * 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;
    
    /**
     * If this is set to <code>true</code>, we attempt to load the translet
     * from the CLASSPATH.
     */
    private boolean _useClasspath = false;

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

    /**
     * The provider of the XSLTC DTM Manager service.  This is fixed for any
     * instance of this class.  In order to change service providers, a new
     * XSLTC <code>TransformerFactory</code> must be instantiated.
     * @see XSLTCDTMManager#getDTMManagerClass()
     */
    private Class m_DTMManagerClass;

    /**
     * javax.xml.transform.sax.TransformerFactory implementation.
     */
    public TransformerFactoryImpl() {
        m_DTMManagerClass = XSLTCDTMManager.getDTMManagerClass();
    }

    /**
     * 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(USE_CLASSPATH)) {
	    if (value instanceof Boolean) {
		_useClasspath = ((Boolean) value).booleanValue();
		return;
	    }
	    else if (value instanceof String) {
		_useClasspath = ((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,
	    SAXTransformerFactory.FEATURE,
	    SAXTransformerFactory.FEATURE_XMLFILTER
	};

	// 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 {

        String baseId;
        XMLReader reader = null;
        InputSource isource = null;


        /**
         * Fix for bugzilla bug 24187
         */
        StylesheetPIHandler _stylesheetPIHandler = new StylesheetPIHandler(null,media,title,charset);

        try {
  
            if (source instanceof DOMSource ) {
                final DOMSource domsrc = (DOMSource) source;
                baseId = domsrc.getSystemId();
                final org.w3c.dom.Node node = domsrc.getNode();
                final DOM2SAX dom2sax = new DOM2SAX(node);

                _stylesheetPIHandler.setBaseId(baseId);

                dom2sax.setContentHandler( _stylesheetPIHandler);
                dom2sax.parse();
            } else {
                isource = SAXSource.sourceToInputSource(source);
                baseId = isource.getSystemId();

                SAXParserFactory factory = SAXParserFactory.newInstance();
                factory.setNamespaceAware(true);
                SAXParser jaxpParser = factory.newSAXParser();

                reader = jaxpParser.getXMLReader();
                if (reader == null) {
                    reader = XMLReaderFactory.createXMLReader();
                }

                _stylesheetPIHandler.setBaseId(baseId);
                reader.setContentHandler(_stylesheetPIHandler);
                reader.parse(isource);

            }

            if (_uriResolver != null ) {
                _stylesheetPIHandler.setURIResolver(_uriResolver);
            }

        } catch (StopParseException e ) {
          // startElement encountered so do not parse further

        } catch (javax.xml.parsers.ParserConfigurationException e) {

             throw new TransformerConfigurationException(
             "getAssociatedStylesheets failed", e);

        } catch (org.xml.sax.SAXException se) {

             throw new TransformerConfigurationException(
             "getAssociatedStylesheets failed", se);


        } catch (IOException ioe ) {
           throw new TransformerConfigurationException(
           "getAssociatedStylesheets failed", ioe);

        }

         return _stylesheetPIHandler.getAssociatedStylesheet();

    }

    /**
     * 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 the _useClasspath attribute is true, try to load the translet from
	// the CLASSPATH and create a template object using the loaded
	// translet.
	if (_useClasspath) {
	    String transletName = getTransletBaseName(source);
	            
	    if (_packageName != null)
	        transletName = _packageName + "." + transletName;
	        
	    try {
                final Class clazz = ObjectFactory.findProviderClass(
                    transletName, ObjectFactory.findClassLoader(), true);
	        resetTransientAttributes();
	            
	        return new TemplatesImpl(new Class[]{clazz}, transletName, null, _indentNumber, this);
	    }
	    catch (ClassNotFoundException cnfe) {
	        ErrorMsg err = new ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR, transletName);
	        throw new TransformerConfigurationException(err.toString());
	    }
	    catch (Exception e) {
	        ErrorMsg err = new ErrorMsg(
                                     new ErrorMsg(ErrorMsg.RUNTIME_ERROR_KEY)
                                     + e.getMessage());
	        throw new TransformerConfigurationException(err.toString());
	    }
	}
	
	// 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 = getTransletBaseName(source);
	    
	    if (_packageName != null)
	        transletClassName = _packageName + "." + transletClassName;
	    
	    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
	    xsltc.setClassName(getTransletBaseName(source));
	  
	    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) {
        
        ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_COMPILE_ERR);
        TransformerConfigurationException exc =  new TransformerConfigurationException(err.toString());
        
        // Pass compiler errors to the error listener
        if (_errorListener != null) {
            passErrorsToListener(xsltc.getErrors());
            
            // As required by TCK 1.2, send a fatalError to the
            // error listener because compilation of the stylesheet
            // failed and no further processing will be possible.
            try {
                _errorListener.fatalError(exc);
            } catch (TransformerException te) {
                // well, we tried.
            }    
        }
        else {
            xsltc.printErrors();
        }
        throw exc;
    }

	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;
    }

    /**
     * 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 base class name of the translet.
     * The translet name is resolved using the following rules:
     * 1. if the _transletName attribute is set and its value is not "GregorSamsa",
     *    then _transletName is returned.
     * 2. otherwise get the translet name from the base name of the system ID
     * 3. return "GregorSamsa" if the result from step 2 is null.
     *
     * @param source The input Source
     * @return The name of the translet class
     */
    private String getTransletBaseName(Source source)
    {      
        String transletBaseName = null;
        if (!_transletName.equals(DEFAULT_TRANSLET_NAME))
            return _transletName;
      	else {
            String systemId = source.getSystemId();
            if (systemId != null) {
          	String baseName = Util.baseName(systemId);
		if (baseName != null) {
		    baseName = Util.noExtName(baseName);
		    transletBaseName = Util.toJavaName(baseName);
		}
            }
      	}
      
        return (transletBaseName != null) ? transletBaseName : DEFAULT_TRANSLET_NAME;
    }
        
    /**
     *  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;
    }

    /**
     * Returns the Class object the provides the XSLTC DTM Manager service.
     */
    protected Class getDTMManagerClass() {
        return m_DTMManagerClass;
    }
}
