/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the  "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * $Id$
 */

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.XMLConstants;
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.xml.utils.StylesheetPIHandler;
import org.apache.xml.utils.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.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.
 * @author G. Todd Miller 
 * @author Morten Jorgensen
 * @author Santiago Pericas-Geertsen
 */
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 final 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;

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

    /**
     * <p>State of secure processing feature.</p>
     */
    private boolean _isSecureProcessing = false;

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

    /**
     * <p>Set a feature for this <code>TransformerFactory</code> and <code>Transformer</code>s
     * or <code>Template</code>s created by this factory.</p>
     * 
     * <p>
     * Feature names are fully qualified {@link java.net.URI}s.
     * Implementations may define their own features.
     * An {@link TransformerConfigurationException} is thrown if this <code>TransformerFactory</code> or the
     * <code>Transformer</code>s or <code>Template</code>s it creates cannot support the feature.
     * It is possible for an <code>TransformerFactory</code> to expose a feature value but be unable to change its state.
     * </p>
     * 
     * <p>See {@link javax.xml.transform.TransformerFactory} for full documentation of specific features.</p>
     * 
     * @param name Feature name.
     * @param value Is feature state <code>true</code> or <code>false</code>.
     *  
     * @throws TransformerConfigurationException if this <code>TransformerFactory</code>
     *   or the <code>Transformer</code>s or <code>Template</code>s it creates cannot support this feature.
     * @throws NullPointerException If the <code>name</code> parameter is null.
     */
    public void setFeature(String name, boolean value)
        throws TransformerConfigurationException {

	// feature name cannot be null
	if (name == null) {
            ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_SET_FEATURE_NULL_NAME);
    	    throw new NullPointerException(err.toString());
	}		
	// secure processing?
	else if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
	    _isSecureProcessing = value;		
	    // all done processing feature
	    return;
	}
	else {	
	    // unknown feature
            ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_UNSUPPORTED_FEATURE, name);
            throw new TransformerConfigurationException(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
	};

	// feature name cannot be null
	if (name == null) {
    	    ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_GET_FEATURE_NULL_NAME);
    	    throw new NullPointerException(err.toString());
	}

	// Inefficient, but array is small
	for (int i =0; i < features.length; i++) {
	    if (name.equals(features[i])) {
		return true;
	    }
	}
	// secure processing?
	if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
		return _isSecureProcessing;
	}

	// 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);
                
                if (_isSecureProcessing) {
                    try {
                        factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
                    }
                    catch (org.xml.sax.SAXException e) {}
                }
                
                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);
	}
	
	if (_isSecureProcessing) {
	    result.setSecureProcessing(true);
	}
	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++) {
	    ErrorMsg msg = (ErrorMsg)messages.elementAt(pos);
	    // Workaround for the TCK failure ErrorListener.errorTests.error001.
	    if (msg.isWarningError())
	        _errorListener.error(
		    new TransformerConfigurationException(msg.toString()));
	    else
	    	_errorListener.warning(
		    new TransformerConfigurationException(msg.toString()));
	}
    }

    /**
     * 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 source 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);
	if (_isSecureProcessing) xsltc.setSecureProcessing(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 templates 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 e 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 e 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 e 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;
    }
}
