FileDocCategorySizeDatePackage
TransformerFactoryImpl.javaAPI DocJava SE 6 API48225Tue Jun 10 00:22:34 BST 2008com.sun.org.apache.xalan.internal.xsltc.trax

TransformerFactoryImpl

public class TransformerFactoryImpl extends SAXTransformerFactory implements ErrorListener, SourceLoader
Implementation of a JAXP1.1 TransformerFactory for Translets.
author
G. Todd Miller
author
Morten Jorgensen
author
Santiago Pericas-Geertsen

Fields Summary
public static final String
TRANSLET_NAME
public static final String
DESTINATION_DIRECTORY
public static final String
PACKAGE_NAME
public static final String
JAR_NAME
public static final String
GENERATE_TRANSLET
public static final String
AUTO_TRANSLET
public static final String
USE_CLASSPATH
public static final String
DEBUG
public static final String
ENABLE_INLINING
public static final String
INDENT_NUMBER
private ErrorListener
_errorListener
This error listener is used only for this factory and is not passed to the Templates or Transformer objects that we create.
private URIResolver
_uriResolver
This URIResolver is passed to all created Templates and Transformers
protected static final String
DEFAULT_TRANSLET_NAME
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....
private String
_transletName
The class name of the translet
private String
_destinationDirectory
The destination directory for the translet
private String
_packageName
The package name prefix for all generated translet classes
private String
_jarFileName
The jar file name which the translet classes are packaged into
private Hashtable
_piParams
This Hashtable is used to store parameters for locating processing instructions in XML docs.
private boolean
_debug
Set to true when debugging is enabled.
private boolean
_enableInlining
Set to true when templates are inlined.
private boolean
_generateTranslet
Set to true when we want to generate translet classes from the stylesheet.
private boolean
_autoTranslet
If this is set to true, 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
_useClasspath
If this is set to true, we attempt to load the translet from the CLASSPATH.
private int
_indentNumber
Number of indent spaces when indentation is turned on.
private Class
m_DTMManagerClass
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 TransformerFactory must be instantiated.
private boolean
_isSecureProcessing

State of secure processing feature.

Constructors Summary
public TransformerFactoryImpl()
javax.xml.transform.sax.TransformerFactory implementation.


           
      
        m_DTMManagerClass = XSLTCDTMManager.getDTMManagerClass();
    
Methods Summary
public voiderror(javax.xml.transform.TransformerException e)
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).

	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; 	
    
public voidfatalError(javax.xml.transform.TransformerException 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).

	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;
    
public javax.xml.transform.SourcegetAssociatedStylesheet(javax.xml.transform.Source source, java.lang.String media, java.lang.String title, java.lang.String charset)
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


        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();

    
public java.lang.ObjectgetAttribute(java.lang.String name)
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

 
	// 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());
    
private byte[][]getBytecodesFromClasses(javax.xml.transform.Source source, java.lang.String fullClassName)
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

    	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;
    
private byte[][]getBytecodesFromJar(javax.xml.transform.Source source, java.lang.String fullClassName)
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

    	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;
    
protected java.lang.ClassgetDTMManagerClass()
Returns the Class object the provides the XSLTC DTM Manager service.

        return m_DTMManagerClass;
    
public javax.xml.transform.ErrorListenergetErrorListener()
javax.xml.transform.sax.TransformerFactory implementation. Get the error event handler for the TransformerFactory.

return
The error listener used with the TransformerFactory

 
	return _errorListener;
    
public booleangetFeature(java.lang.String name)
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

 
	// 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;
    
private java.lang.StringgetStylesheetFileName(javax.xml.transform.Source source)
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.

    	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;
    
private java.lang.StringgetTransletBaseName(javax.xml.transform.Source source)
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

      
        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;
    
public javax.xml.transform.URIResolvergetURIResolver()
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

	return _uriResolver;
    
public org.xml.sax.InputSourceloadSource(java.lang.String href, java.lang.String context, com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC xsltc)
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

	try {
	    if (_uriResolver != null) {
		final Source source = _uriResolver.resolve(href, context);
		if (source != null) {
		    return Util.getInputSource(xsltc, source);
		}
	    }
	}
	catch (TransformerException e) {            
	    // should catch it when the resolver explicitly throws the exception 
            final ErrorMsg msg = new ErrorMsg(ErrorMsg.INVALID_URI_ERR, href + "\n" + e.getMessage(), this);
            xsltc.getParser().reportError(Constants.FATAL, msg);
	}
 
	return null;
    
public javax.xml.transform.TemplatesnewTemplates(javax.xml.transform.Source source)
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

	// 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);
    
public javax.xml.transform.sax.TemplatesHandlernewTemplatesHandler()
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

 
	final TemplatesHandlerImpl handler = 
	    new TemplatesHandlerImpl(_indentNumber, this);
	if (_uriResolver != null) {
	    handler.setURIResolver(_uriResolver);
	}
	return handler;
    
public javax.xml.transform.TransformernewTransformer()
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

 
	TransformerImpl result = new TransformerImpl(new Properties(), 
	    _indentNumber, this);
	if (_uriResolver != null) {
	    result.setURIResolver(_uriResolver);
	}
	
	if (_isSecureProcessing) {
	    result.setSecureProcessing(true);
	}
	return result;
    
public javax.xml.transform.TransformernewTransformer(javax.xml.transform.Source source)
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

	final Templates templates = newTemplates(source);
	final Transformer transformer = templates.newTransformer();
	if (_uriResolver != null) {
	    transformer.setURIResolver(_uriResolver);
	}
	return(transformer);
    
public javax.xml.transform.sax.TransformerHandlernewTransformerHandler()
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

	final Transformer transformer = newTransformer();
	if (_uriResolver != null) {
	    transformer.setURIResolver(_uriResolver);
	}
	return new TransformerHandlerImpl((TransformerImpl) transformer);
    
public javax.xml.transform.sax.TransformerHandlernewTransformerHandler(javax.xml.transform.Source src)
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

 
	final Transformer transformer = newTransformer(src);
	if (_uriResolver != null) {
	    transformer.setURIResolver(_uriResolver);
	}
	return new TransformerHandlerImpl((TransformerImpl) transformer);
    
public javax.xml.transform.sax.TransformerHandlernewTransformerHandler(javax.xml.transform.Templates templates)
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

	final Transformer transformer = templates.newTransformer();
	final TransformerImpl internal = (TransformerImpl)transformer;
	return new TransformerHandlerImpl(internal);
    
public org.xml.sax.XMLFilternewXMLFilter(javax.xml.transform.Source src)
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

	Templates templates = newTemplates(src);
	if (templates == null) return null; 
	return newXMLFilter(templates);
    
public org.xml.sax.XMLFilternewXMLFilter(javax.xml.transform.Templates 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

	try {
      	    return new com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter(templates);
    	}
	catch (TransformerConfigurationException e1) {
      	    if (_errorListener != null) {
                try {
          	    _errorListener.fatalError(e1);
          	    return null;
        	}
		catch (TransformerException e2) {
          	    new TransformerConfigurationException(e2);
        	}
      	    }
      	    throw e1;
    	}
    
private voidpassErrorsToListener(java.util.Vector messages)
Pass error messages from the compiler to the error listener

	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
	}
    
private voidpassWarningsToListener(java.util.Vector messages)
Pass warning messages from the compiler to the error listener

	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()));
	}
    
private voidreadFromInputStream(byte[] bytes, java.io.InputStream input, int size)
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.

      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;
      }    
    
private voidresetTransientAttributes()
Reset the per-session attributes to their default values

	_transletName = DEFAULT_TRANSLET_NAME;
	_destinationDirectory = null;
	_packageName = null;
	_jarFileName = null;    
    
public voidsetAttribute(java.lang.String name, java.lang.Object value)
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

 
	// 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());
    
public voidsetErrorListener(javax.xml.transform.ErrorListener listener)
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

	if (listener == null) {
	    ErrorMsg err = new ErrorMsg(ErrorMsg.ERROR_LISTENER_NULL_ERR,
					"TransformerFactory");
            throw new IllegalArgumentException(err.toString());
	}
	_errorListener = listener;
    
public voidsetFeature(java.lang.String name, boolean value)

Set a feature for this TransformerFactory and Transformers or Templates created by this factory.

Feature names are fully qualified {@link java.net.URI}s. Implementations may define their own features. An {@link TransformerConfigurationException} is thrown if this TransformerFactory or the Transformers or Templates it creates cannot support the feature. It is possible for an TransformerFactory to expose a feature value but be unable to change its state.

See {@link javax.xml.transform.TransformerFactory} for full documentation of specific features.

param
name Feature name.
param
value Is feature state true or false.
throws
TransformerConfigurationException if this TransformerFactory or the Transformers or Templates it creates cannot support this feature.
throws
NullPointerException If the name parameter is null.


	// 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());
        }
    
public voidsetURIResolver(javax.xml.transform.URIResolver resolver)
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

	_uriResolver = resolver;
    
public voidwarning(javax.xml.transform.TransformerException 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).

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