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

TransformerImpl

public final class TransformerImpl extends Transformer implements ErrorListener, DOMCache
author
Morten Jorgensen
author
G. Todd Miller
author
Santiago Pericas-Geertsen

Fields Summary
private static final String
EMPTY_STRING
private static final String
NO_STRING
private static final String
YES_STRING
private static final String
XML_STRING
private static final String
LEXICAL_HANDLER_PROPERTY
private static final String
NAMESPACE_FEATURE
private static final String
NAMESPACE_PREFIXES_FEATURE
Namespace prefixes feature for {@link XMLReader}.
private AbstractTranslet
_translet
A reference to the translet or null if the identity transform.
private String
_method
The output method of this transformation.
private String
_encoding
The output encoding of this transformation.
private String
_sourceSystemId
The systemId set in input source.
private ErrorListener
_errorListener
An error listener for runtime errors.
private URIResolver
_uriResolver
A reference to a URI resolver for calls to document().
private Properties
_properties
Output properties of this transformer instance.
private Properties
_propertiesClone
private TransletOutputHandlerFactory
_tohFactory
A reference to an output handler factory.
private DOM
_dom
A reference to a internal DOM represenation of the input.
private int
_indentNumber
Number of indent spaces to add when indentation is on.
private TransformerFactoryImpl
_tfactory
A reference to the transformer factory that this templates object belongs to.
private OutputStream
_ostream
A reference to the output stream, if we create one in our code.
private XSLTCDTMManager
_dtmManager
A reference to the XSLTCDTMManager which is used to build the DOM/DTM for this transformer.
private XMLReaderManager
_readerManager
A reference to an object that creates and caches XMLReader objects.
private boolean
_isIdentity
A flag indicating whether this transformer implements the identity transform.
private boolean
_isSecureProcessing
State of the secure processing feature.
private com.sun.org.apache.xalan.internal.xsltc.runtime.Hashtable
_parameters
A hashtable to store parameters for the identity transform. These are not needed during the transformation, but we must keep track of them to be fully complaint with the JAXP API.
Constructors Summary
protected TransformerImpl(Properties outputProperties, int indentNumber, TransformerFactoryImpl tfactory)

	this(null, outputProperties, indentNumber, tfactory);
	_isIdentity = true;
	// _properties.put(OutputKeys.METHOD, "xml");
    
protected TransformerImpl(Translet translet, Properties outputProperties, int indentNumber, TransformerFactoryImpl tfactory)

	_translet = (AbstractTranslet) translet;
	_properties = createOutputProperties(outputProperties);
	_propertiesClone = (Properties) _properties.clone();
	_indentNumber = indentNumber;
	_tfactory = tfactory;
	//_isIncremental = tfactory._incremental;
    
Methods Summary
public voidclearParameters()
Implements JAXP's Transformer.clearParameters() Clear all parameters set with setParameter. Clears the translet's parameter stack.

  
	if (_isIdentity && _parameters != null) {
	    _parameters.clear();
	}
	else {
	    _translet.clearParameters();
	}
    
private java.util.PropertiescreateOutputProperties(java.util.Properties outputProperties)
Internal method to create the initial set of properties. There are two layers of properties: the default layer and the base layer. The latter contains properties defined in the stylesheet or by the user using this API.

	final Properties defaults = new Properties();
	setDefaults(defaults, "xml");

	// Copy propeties set in stylesheet to base
	final Properties base = new Properties(defaults);
	if (outputProperties != null) {
	    final Enumeration names = outputProperties.propertyNames();
	    while (names.hasMoreElements()) {
		final String name = (String) names.nextElement();
		base.setProperty(name, outputProperties.getProperty(name));
	    }
	}
	else {
	    base.setProperty(OutputKeys.ENCODING, _translet._encoding);
	    if (_translet._method != null)
	        base.setProperty(OutputKeys.METHOD, _translet._method);
	}

	// Update defaults based on output method
	final String method = base.getProperty(OutputKeys.METHOD);
	if (method != null) {
	    if (method.equals("html")) {
	        setDefaults(defaults,"html");
	    }
	    else if (method.equals("text")) {
	        setDefaults(defaults,"text");
	    }
	}

	return base; 
    
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 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.FATAL_ERR_PLUS_WRAPPED_MSG,
                                            e.getMessageAndLocation(),
                                            wrapped.getMessage()));
        } else {
            System.err.println(new ErrorMsg(ErrorMsg.FATAL_ERR_MSG,
                                            e.getMessageAndLocation()));
        }
        throw e;
    
private com.sun.org.apache.xalan.internal.xsltc.DOMgetDOM(javax.xml.transform.Source source)
Builds an internal DOM from a TrAX Source object

        try {
            DOM dom = null;

            if (source != null) {
                DTMWSFilter wsfilter;
                if (_translet != null && _translet instanceof StripFilter) {
                    wsfilter = new DOMWSFilter(_translet);
                 } else {
                    wsfilter = null;
                 }
            
                 boolean hasIdCall = (_translet != null) ? _translet.hasIdCall()
                                                         : false;

                 if (_dtmManager == null) {
                     _dtmManager =
                         (XSLTCDTMManager)_tfactory.getDTMManagerClass()
                                                   .newInstance();
                 }
                 dom = (DOM)_dtmManager.getDTM(source, false, wsfilter, true,
                                              false, false, 0, hasIdCall);
            } else if (_dom != null) {
                 dom = _dom;
                 _dom = null;  // use only once, so reset to 'null'
            } else {
                 return null;
            }

            if (!_isIdentity) {
                // Give the translet the opportunity to make a prepass of
                // the document, in case it can extract useful information early
                _translet.prepassDocument(dom);
            }

            return dom;

        }
        catch (Exception e) {
            if (_errorListener != null) {
                postErrorToListener(e.getMessage());
            }
            throw new TransformerException(e);
        }
    
public javax.xml.transform.ErrorListenergetErrorListener()
Implements JAXP's Transformer.getErrorListener() Get the error event handler in effect for the transformation.

return
The error event handler currently in effect

  
	return _errorListener; 
    
public com.sun.org.apache.xml.internal.serializer.SerializationHandlergetOutputHandler(javax.xml.transform.Result result)
Create an output handler for the transformation output based on the type and contents of the TrAX Result object passed to the transform() method.

	// Get output method using get() to ignore defaults 
	_method = (String) _properties.get(OutputKeys.METHOD);

	// Get encoding using getProperty() to use defaults
	_encoding = (String) _properties.getProperty(OutputKeys.ENCODING);

	_tohFactory = TransletOutputHandlerFactory.newInstance();
	_tohFactory.setEncoding(_encoding);
	if (_method != null) {
	    _tohFactory.setOutputMethod(_method);
	}

	// Set indentation number in the factory
	if (_indentNumber >= 0) {
	    _tohFactory.setIndentNumber(_indentNumber);
	}

	// Return the content handler for this Result object
	try {
	    // Result object could be SAXResult, DOMResult, or StreamResult 
	    if (result instanceof SAXResult) {
                final SAXResult target = (SAXResult)result;
                final ContentHandler handler = target.getHandler();

		_tohFactory.setHandler(handler);

                /**
                 * Fix for bug 24414
                 * If the lexicalHandler is set then we need to get that
                 * for obtaining the lexical information 
                 */
                LexicalHandler lexicalHandler = target.getLexicalHandler();

                if (lexicalHandler != null ) {
		    _tohFactory.setLexicalHandler(lexicalHandler);
		}

		_tohFactory.setOutputType(TransletOutputHandlerFactory.SAX);
		return _tohFactory.getSerializationHandler();
            }
            else if (result instanceof StAXResult) {
                if (((StAXResult) result).getXMLEventWriter() != null) 
                    _tohFactory.setXMLEventWriter(((StAXResult) result).getXMLEventWriter());
                else if (((StAXResult) result).getXMLStreamWriter() != null) 
                    _tohFactory.setXMLStreamWriter(((StAXResult) result).getXMLStreamWriter());
                _tohFactory.setOutputType(TransletOutputHandlerFactory.STAX);
                return _tohFactory.getSerializationHandler();
            }
	    else if (result instanceof DOMResult) {
		_tohFactory.setNode(((DOMResult) result).getNode());
		_tohFactory.setNextSibling(((DOMResult) result).getNextSibling());
		_tohFactory.setOutputType(TransletOutputHandlerFactory.DOM);
		return _tohFactory.getSerializationHandler();
            }
	    else if (result instanceof StreamResult) {
		// Get StreamResult
		final StreamResult target = (StreamResult) result;	

		// StreamResult may have been created with a java.io.File,
		// java.io.Writer, java.io.OutputStream or just a String
		// systemId. 

		_tohFactory.setOutputType(TransletOutputHandlerFactory.STREAM);

		// try to get a Writer from Result object
		final Writer writer = target.getWriter();
		if (writer != null) {
		    _tohFactory.setWriter(writer);
		    return _tohFactory.getSerializationHandler();
		}

		// or try to get an OutputStream from Result object
		final OutputStream ostream = target.getOutputStream();
		if (ostream != null) {
		    _tohFactory.setOutputStream(ostream);
		    return _tohFactory.getSerializationHandler();
		}

		// or try to get just a systemId string from Result object
		String systemId = result.getSystemId();
		if (systemId == null) {
		    ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_RESULT_ERR);
                    throw new TransformerException(err.toString());
		}

		// System Id may be in one of several forms, (1) a uri
		// that starts with 'file:', (2) uri that starts with 'http:'
		// or (3) just a filename on the local system.
		URL url = null;
                if (systemId.startsWith("file:")) {
                    // if StreamResult(File) or setSystemID(File) was used,
                    // the systemId will be URI encoded as a result of File.toURI(),
                    // it must be decoded for use by URL
                    try{
                        Class clazz =   ObjectFactory.findProviderClass("java.net.URI", ObjectFactory.findClassLoader(), true);
                        Constructor  construct   = clazz.getConstructor(new Class[] {java.lang.String.class} );
                        URI uri = (URI) construct.newInstance(new Object[]{systemId}) ;
                        systemId = "file:";

                        String host = uri.getHost(); // decoded String
                        String path = uri.getPath(); //decoded String
                        if (path == null) {
                         path = "";   
                        }

                        // if host (URI authority) then file:// + host + path
                        // else just path (may be absolute or relative)
                        if (host != null) {
                         systemId += "//" + host + path;   
                        } else {
                         systemId += "//" + path;   
                        }
                    }
                    catch(ClassNotFoundException e){
                        // running on J2SE 1.3 which doesn't have URI Class so OK to ignore
                        //ClassNotFoundException.
                    }
                    catch (Exception  exception) {
                        // URI exception which means nothing can be done so OK to ignore
                    }
                        
                    url = new URL(systemId);
                    _ostream = new FileOutputStream(url.getFile());
		    _tohFactory.setOutputStream(_ostream);
		    return _tohFactory.getSerializationHandler();
                }
                else if (systemId.startsWith("http:")) {
                    url = new URL(systemId);
                    final URLConnection connection = url.openConnection();
		    _tohFactory.setOutputStream(_ostream = connection.getOutputStream());
		    return _tohFactory.getSerializationHandler();
                }
                else {
                    // system id is just a filename
                    url = new File(systemId).toURL();
		    _tohFactory.setOutputStream(
		        _ostream = new FileOutputStream(url.getFile()));
		    return _tohFactory.getSerializationHandler();
                }
	    }
	}
        // If we cannot write to the location specified by the SystemId
        catch (UnknownServiceException e) {
            throw new TransformerException(e);
        }
        catch (ParserConfigurationException e) {
            throw new TransformerException(e);
        }
        // If we cannot create the file specified by the SystemId
        catch (IOException e) {
            throw new TransformerException(e);
        }
	return null;
    
public java.util.PropertiesgetOutputProperties()
Implements JAXP's Transformer.getOutputProperties(). Returns a copy of the output properties for the transformation. This is a set of layered properties. The first layer contains properties set by calls to setOutputProperty() and setOutputProperties() on this class, and the output settings defined in the stylesheet's element makes up the second level, while the default XSLT output settings are returned on the third level.

return
Properties in effect for this Transformer

 
	return (Properties) _properties.clone();
    
public java.lang.StringgetOutputProperty(java.lang.String name)
Implements JAXP's Transformer.getOutputProperty(). Get an output property that is in effect for the transformation. The property specified may be a property that was set with setOutputProperty, or it may be a property specified in the stylesheet.

param
name A non-null string that contains the name of the property
throws
IllegalArgumentException if the property name is not known

	if (!validOutputProperty(name)) {
	    ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_UNKNOWN_PROP_ERR, name);
	    throw new IllegalArgumentException(err.toString());
	}
	return _properties.getProperty(name);
    
public final java.lang.ObjectgetParameter(java.lang.String name)
Implements JAXP's Transformer.getParameter() Returns the value of a given parameter. Note that the translet will not keep values for parameters that were not defined in the stylesheet.

param
name The name of the parameter
return
An object that contains the value assigned to the parameter

	if (_isIdentity) {
	    return (_parameters != null) ? _parameters.get(name) : null;
	}
	else {
	    return _translet.getParameter(name);
	}
    
protected com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImplgetTransformerFactory()
Returns the {@link com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl} object that create this Transformer.

        return _tfactory;
    
protected com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTransletgetTranslet()
Returns the translet wrapped inside this Transformer or null if this is the identity transform.

	return _translet;
    
protected com.sun.org.apache.xalan.internal.xsltc.runtime.output.TransletOutputHandlerFactorygetTransletOutputHandlerFactory()
Returns the {@link com.sun.org.apache.xalan.internal.xsltc.runtime.output.TransletOutputHandlerFactory} object that create the TransletOutputHandler.

        return _tohFactory;
    
public javax.xml.transform.URIResolvergetURIResolver()
Implements JAXP's Transformer.getURIResolver() Set the object currently used to resolve URIs used in document().

return
The URLResolver object currently in use

	return _uriResolver;
    
private booleanisDefaultProperty(java.lang.String name, java.util.Properties properties)
Checks if a given output property is default (2nd layer only)

	return (properties.get(name) == null);
    
public booleanisIdentity()

	return _isIdentity;
    
public booleanisSecureProcessing()
Return the state of the secure processing feature.

        return _isSecureProcessing;
    
private java.lang.StringmakeCDATAString(com.sun.org.apache.xalan.internal.xsltc.runtime.Hashtable cdata)
The translet stores all CDATA sections set in the element in a Hashtable. This method will re-construct the whitespace separated list of elements given in the element.

	// Return a 'null' string if no CDATA section elements were specified
	if (cdata == null) return null;

	StringBuffer result = new StringBuffer();

	// Get an enumeration of all the elements in the hashtable
	Enumeration elements = cdata.keys();
	if (elements.hasMoreElements()) {
	    result.append((String)elements.nextElement());
	    while (elements.hasMoreElements()) {
		String element = (String)elements.nextElement();
		result.append(' ");
		result.append(element);
	    }
	}
	
	return(result.toString());
    
private voidpostErrorToListener(java.lang.String message)
Inform TrAX error listener of an error

        try {
            _errorListener.error(new TransformerException(message));
	}
	catch (TransformerException e) {
            // ignored - transformation cannot be continued
        }
    
private voidpostWarningToListener(java.lang.String message)
Inform TrAX error listener of a warning

        try {
            _errorListener.warning(new TransformerException(message));
        }
	catch (TransformerException e) {
            // ignored - transformation cannot be continued
        }
    
public voidreset()
This method resets the Transformer to its original configuration Transformer code is reset to the same state it was when it was created

since
1.5


        _method = null;
        _encoding = null;
        _sourceSystemId = null;
        _errorListener = this;
        _uriResolver = null;
        _dom = null;
        _parameters = null;
        _indentNumber = 0;
        setOutputProperties (null);

    
public com.sun.org.apache.xalan.internal.xsltc.DOMretrieveDocument(java.lang.String baseURI, java.lang.String href, com.sun.org.apache.xalan.internal.xsltc.Translet translet)
This class should only be used as a DOMCache for the translet if the URIResolver has been set. The method implements XSLTC's DOMCache interface, which is used to plug in an external document loader into a translet. This method acts as an adapter between TrAX's URIResolver interface and XSLTC's DOMCache interface. This approach is simple, but removes the possibility of using external document caches with XSLTC.

param
baseURI The base URI used by the document call.
param
href The href argument passed to the document function.
param
translet A reference to the translet requesting the document

	try {        
            // Argument to document function was: document('');
            if (href.length() == 0) {
                href = new String(baseURI);
            }    

            /*
             *  Fix for bug 24188
             *  Incase the _uriResolver.resolve(href,base) is null
             *  try to still  retrieve the document before returning null 
             *  and throwing the FileNotFoundException in
             *  com.sun.org.apache.xalan.internal.xsltc.dom.LoadDocument
             *
             */
            Source resolvedSource = _uriResolver.resolve(href, baseURI);
            if (resolvedSource == null)  {
                StreamSource streamSource = new StreamSource(
                     SystemIDResolver.getAbsoluteURI(href, baseURI));
                return getDOM(streamSource) ;
            } 

            return getDOM(resolvedSource);
	}
	catch (TransformerException e) {
	    if (_errorListener != null)
		postErrorToListener("File not found: " + e.getMessage());
	    return(null);
	}
    
protected voidsetDOM(com.sun.org.apache.xalan.internal.xsltc.DOM dom)
Set the internal DOM that will be used for the next transformation

	_dom = dom;
    
private voidsetDefaults(java.util.Properties props, java.lang.String method)
Internal method to get the default properties from the serializer factory and set them on the property object.

param
props a java.util.Property object on which the properties are set.
param
method The output method type, one of "xml", "text", "html" ...

		final Properties method_props =
			OutputPropertiesFactory.getDefaultMethodProperties(method);
		{
			final Enumeration names = method_props.propertyNames();
			while (names.hasMoreElements())
			{
				final String name = (String)names.nextElement();
				props.setProperty(name, method_props.getProperty(name));
			}
		}
	
public voidsetErrorListener(javax.xml.transform.ErrorListener listener)
Implements JAXP's Transformer.setErrorListener() Set the error event listener in effect for the transformation. Register a message handler in the translet in order to forward xsl:messages to error listener.

param
listener The error event listener to use
throws
IllegalArgumentException

        if (listener == null) {
	    ErrorMsg err = new ErrorMsg(ErrorMsg.ERROR_LISTENER_NULL_ERR,
					"Transformer");
            throw new IllegalArgumentException(err.toString());
	}
        _errorListener = listener;
        
	// Register a message handler to report xsl:messages
    if (_translet != null)
    	_translet.setMessageHandler(new MessageHandler(_errorListener));
    
public voidsetOutputProperties(java.util.Properties properties)
Implements JAXP's Transformer.setOutputProperties(). Set the output properties for the transformation. These properties will override properties set in the Templates with xsl:output. Unrecognised properties will be quitely ignored.

param
properties The properties to use for the Transformer
throws
IllegalArgumentException Never, errors are ignored

	if (properties != null) {
	    final Enumeration names = properties.propertyNames();

	    while (names.hasMoreElements()) {
		final String name = (String) names.nextElement();

		// Ignore lower layer properties
		if (isDefaultProperty(name, properties)) continue;

		if (validOutputProperty(name)) {
		    _properties.setProperty(name, properties.getProperty(name));
		}
		else {
		    ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_UNKNOWN_PROP_ERR, name);
		    throw new IllegalArgumentException(err.toString());
		}
	    }
	}
	else {
	    _properties = _propertiesClone;
	}
    
public voidsetOutputProperty(java.lang.String name, java.lang.String value)
Implements JAXP's Transformer.setOutputProperty(). Get an output property that is in effect for the transformation. The property specified may be a property that was set with setOutputProperty(), or it may be a property specified in the stylesheet.

param
name The name of the property to set
param
value The value to assign to the property
throws
IllegalArgumentException Never, errors are ignored

	if (!validOutputProperty(name)) {
	    ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_UNKNOWN_PROP_ERR, name);
	    throw new IllegalArgumentException(err.toString());
	}
	_properties.setProperty(name, value);
    
public voidsetParameter(java.lang.String name, java.lang.Object value)
Implements JAXP's Transformer.setParameter() Add a parameter for the transformation. The parameter is simply passed on to the translet - no validation is performed - so any unused parameters are quitely ignored by the translet.

param
name The name of the parameter
param
value The value to assign to the parameter

        
        if (value == null) {
            ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_INVALID_SET_PARAM_VALUE, name);
            throw new IllegalArgumentException(err.toString());
        }
             
	if (_isIdentity) {
	    if (_parameters == null) {
		_parameters = new Hashtable();
	    }
	    _parameters.put(name, value);
	}
	else {
	    _translet.addParameter(name, value);
	}
    
public voidsetSecureProcessing(boolean flag)
Set the state of the secure processing feature.

        _isSecureProcessing = flag;
    
public voidsetURIResolver(javax.xml.transform.URIResolver resolver)
Implements JAXP's Transformer.setURIResolver() Set an object that will be used to resolve URIs used in document().

param
resolver The URIResolver to use in document()

 
	_uriResolver = resolver;
    
private voidtransferOutputProperties(com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet translet)
Internal method to pass any properties to the translet prior to initiating the transformation

	// Return right now if no properties are set
	if (_properties == null) return;

	// Get a list of all the defined properties
	Enumeration names = _properties.propertyNames();
	while (names.hasMoreElements()) {
	    // Note the use of get() instead of getProperty()
	    String name  = (String) names.nextElement();
	    String value = (String) _properties.get(name);

	    // Ignore default properties
	    if (value == null) continue;

	    // Pass property value to translet - override previous setting
	    if (name.equals(OutputKeys.ENCODING)) {
		translet._encoding = value;
	    }
	    else if (name.equals(OutputKeys.METHOD)) {
		translet._method = value;
	    }
	    else if (name.equals(OutputKeys.DOCTYPE_PUBLIC)) {
		translet._doctypePublic = value;
	    }
	    else if (name.equals(OutputKeys.DOCTYPE_SYSTEM)) {
		translet._doctypeSystem = value;
	    }
	    else if (name.equals(OutputKeys.MEDIA_TYPE)) {
		translet._mediaType = value;
	    }
	    else if (name.equals(OutputKeys.STANDALONE)) {
		translet._standalone = value;
	    }
	    else if (name.equals(OutputKeys.VERSION)) {
		translet._version = value;
	    }
	    else if (name.equals(OutputKeys.OMIT_XML_DECLARATION)) {
		translet._omitHeader = 
		    (value != null && value.toLowerCase().equals("yes"));
	    }
	    else if (name.equals(OutputKeys.INDENT)) {
		translet._indent = 
		    (value != null && value.toLowerCase().equals("yes"));
	    }
            else if (name.equals(OutputPropertiesFactory.S_BUILTIN_OLD_EXTENSIONS_UNIVERSAL +"indent-amount")) {
                 if (value != null) {
                     translet._indentamount = Integer.parseInt(value);
                 }
            }
            else if (name.equals(OutputPropertiesFactory.S_BUILTIN_EXTENSIONS_UNIVERSAL +"indent-amount")) {
                 if (value != null) {
                     translet._indentamount = Integer.parseInt(value);
                 }
            }
	    else if (name.equals(OutputKeys.CDATA_SECTION_ELEMENTS)) {
		if (value != null) {
		    translet._cdata = null; // clear previous setting
		    StringTokenizer e = new StringTokenizer(value);
		    while (e.hasMoreTokens()) {
			translet.addCdataElement(e.nextToken());
		    }
		}
	    }
	}
    
public voidtransferOutputProperties(com.sun.org.apache.xml.internal.serializer.SerializationHandler handler)
This method is used to pass any properties to the output handler when running the identity transform.

	// Return right now if no properties are set
	if (_properties == null) return;

	String doctypePublic = null;
	String doctypeSystem = null;

	// Get a list of all the defined properties
	Enumeration names = _properties.propertyNames();
	while (names.hasMoreElements()) {
	    // Note the use of get() instead of getProperty()
	    String name  = (String) names.nextElement();
	    String value = (String) _properties.get(name);

	    // Ignore default properties
	    if (value == null) continue;

	    // Pass property value to translet - override previous setting
	    if (name.equals(OutputKeys.DOCTYPE_PUBLIC)) {
		doctypePublic = value;
	    }
	    else if (name.equals(OutputKeys.DOCTYPE_SYSTEM)) {
		doctypeSystem = value;
	    }
	    else if (name.equals(OutputKeys.MEDIA_TYPE)) {
		handler.setMediaType(value);
	    }
	    else if (name.equals(OutputKeys.STANDALONE)) {
		handler.setStandalone(value);
	    }
	    else if (name.equals(OutputKeys.VERSION)) {
		handler.setVersion(value);
	    }
	    else if (name.equals(OutputKeys.OMIT_XML_DECLARATION)) {
		handler.setOmitXMLDeclaration(
		    value != null && value.toLowerCase().equals("yes"));
	    }
	    else if (name.equals(OutputKeys.INDENT)) {
		handler.setIndent( 
		    value != null && value.toLowerCase().equals("yes"));
	    }
            else if (name.equals(OutputPropertiesFactory.S_BUILTIN_OLD_EXTENSIONS_UNIVERSAL +"indent-amount")) {
                if (value != null) {
                    handler.setIndentAmount(Integer.parseInt(value));
                }
            }
            else if (name.equals(OutputPropertiesFactory.S_BUILTIN_EXTENSIONS_UNIVERSAL +"indent-amount")) {
                if (value != null) {
                    handler.setIndentAmount(Integer.parseInt(value));
                }
            } 
	    else if (name.equals(OutputKeys.CDATA_SECTION_ELEMENTS)) {
		if (value != null) {
		    StringTokenizer e = new StringTokenizer(value);
                    Vector uriAndLocalNames = null;
		    while (e.hasMoreTokens()) {
			final String token = e.nextToken();

                        // look for the last colon, as the String may be
                        // something like "http://abc.com:local"
                        int lastcolon = token.lastIndexOf(':");
                        String uri;
                        String localName;
                        if (lastcolon > 0) {
                            uri = token.substring(0, lastcolon);
                            localName = token.substring(lastcolon+1);
                        } else {
                            // no colon at all, lets hope this is the
                            // local name itself then
                            uri = null;
                            localName = token;
                        }

                        if (uriAndLocalNames == null) {
                            uriAndLocalNames = new Vector();
                        }
                        // add the uri/localName as a pair, in that order
                        uriAndLocalNames.addElement(uri);
                        uriAndLocalNames.addElement(localName);
                    }
                    handler.setCdataSectionElements(uriAndLocalNames);
		}
	    }
	}

	// Call setDoctype() if needed
	if (doctypePublic != null || doctypeSystem != null) {
	    handler.setDoctype(doctypeSystem, doctypePublic);
	}
    
private voidtransform(javax.xml.transform.Source source, com.sun.org.apache.xml.internal.serializer.SerializationHandler handler, java.lang.String encoding)
Internal transformation method - uses the internal APIs of XSLTC

	try {
            /*
             * According to JAXP1.2, new SAXSource()/StreamSource()
             * should create an empty input tree, with a default root node. 
             * new DOMSource()creates an empty document using DocumentBuilder.
             * newDocument(); Use DocumentBuilder.newDocument() for all 3 
             * situations, since there is no clear spec. how to create 
             * an empty tree when both SAXSource() and StreamSource() are used.
             */
            if ((source instanceof StreamSource && source.getSystemId()==null 
                && ((StreamSource)source).getInputStream()==null &&
                ((StreamSource)source).getReader()==null)||
                (source instanceof SAXSource &&
                ((SAXSource)source).getInputSource()==null &&
                ((SAXSource)source).getXMLReader()==null )||
                (source instanceof DOMSource && 
                ((DOMSource)source).getNode()==null)){
                        DocumentBuilderFactory builderF = 
                                DocumentBuilderFactory.newInstance();
                        DocumentBuilder builder = 
                                builderF.newDocumentBuilder();
                        String systemID = source.getSystemId();
                        source = new DOMSource(builder.newDocument());

                        // Copy system ID from original, empty Source to new
                        if (systemID != null) {
                          source.setSystemId(systemID);
                        }
            }           
	    if (_isIdentity) {
		transformIdentity(source, handler);
	    } else {
		_translet.transform(getDOM(source), handler);
	    }
	} catch (TransletException e) {
	    if (_errorListener != null)	postErrorToListener(e.getMessage());
	    throw new TransformerException(e);
	} catch (RuntimeException e) {
	    if (_errorListener != null)	postErrorToListener(e.getMessage());
	    throw new TransformerException(e);
	} catch (Exception e) {
	    if (_errorListener != null)	postErrorToListener(e.getMessage());
	    throw new TransformerException(e);
	} finally {
            _dtmManager = null;
        }

	// If we create an output stream for the Result, we need to close it after the transformation.
	if (_ostream != null) {
	    try {
	        _ostream.close();
	    }
	    catch (IOException e) {}
	    _ostream = null;
	}
    
public voidtransform(javax.xml.transform.Source source, javax.xml.transform.Result result)
Implements JAXP's Transformer.transform()

param
source Contains the input XML document
param
result Will contain the output from the transformation
throws
TransformerException

	if (!_isIdentity) {
	    if (_translet == null) {
		ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_TRANSLET_ERR);
		throw new TransformerException(err.toString());
	    }
	    // Pass output properties to the translet
	    transferOutputProperties(_translet);
	}
	    
	final SerializationHandler toHandler = getOutputHandler(result);
	if (toHandler == null) {
	    ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_HANDLER_ERR);
	    throw new TransformerException(err.toString());
	}

	if (_uriResolver != null && !_isIdentity) {
	    _translet.setDOMCache(this);
	}

	// Pass output properties to handler if identity
	if (_isIdentity) {
	    transferOutputProperties(toHandler);
	}

	transform(source, toHandler, _encoding);
        try{
            if (result instanceof DOMResult) {
                ((DOMResult)result).setNode(_tohFactory.getNode());
            } else if (result instanceof StAXResult) {
                  if (((StAXResult) result).getXMLEventWriter() != null)
                {
                    (_tohFactory.getXMLEventWriter()).flush();
                }
                else if (((StAXResult) result).getXMLStreamWriter() != null) {
                    (_tohFactory.getXMLStreamWriter()).flush();
                    //result = new StAXResult(_tohFactory.getXMLStreamWriter());
                }
            }
        } catch (Exception e) {
            System.out.println("Result writing error");
        }
    
private voidtransformIdentity(javax.xml.transform.Source source, com.sun.org.apache.xml.internal.serializer.SerializationHandler handler)

        // Get systemId from source
        if (source != null) {
            _sourceSystemId = source.getSystemId();
        }

        if (source instanceof StreamSource) {
            final StreamSource stream = (StreamSource) source;
            final InputStream streamInput = stream.getInputStream();
            final Reader streamReader = stream.getReader();
            final XMLReader reader = _readerManager.getXMLReader();

            try {
                // Hook up reader and output handler
                try {
                    reader.setProperty(LEXICAL_HANDLER_PROPERTY, handler);
                    reader.setFeature(NAMESPACE_PREFIXES_FEATURE, true);
                } catch (SAXException e) {
                    // Falls through
                }
                reader.setContentHandler(handler);

                // Create input source from source
                InputSource input;
                if (streamInput != null) {
                    input = new InputSource(streamInput);
                    input.setSystemId(_sourceSystemId); 
                } 
                else if (streamReader != null) {
                    input = new InputSource(streamReader);
                    input.setSystemId(_sourceSystemId); 
                } 
                else if (_sourceSystemId != null) {
                    input = new InputSource(_sourceSystemId);
                } 
                else {
                    ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_SOURCE_ERR);
                    throw new TransformerException(err.toString());
                }

                // Start pushing SAX events
                reader.parse(input);
            } finally {
                _readerManager.releaseXMLReader(reader);
            }
        } else if (source instanceof SAXSource) {
            final SAXSource sax = (SAXSource) source;
            XMLReader reader = sax.getXMLReader();
            final InputSource input = sax.getInputSource();
            boolean userReader = true;

            try {
                // Create a reader if not set by user
                if (reader == null) {
                    reader = _readerManager.getXMLReader();
                    userReader = false;
                }

                // Hook up reader and output handler
                try {
                    reader.setProperty(LEXICAL_HANDLER_PROPERTY, handler);
                    reader.setFeature(NAMESPACE_PREFIXES_FEATURE, true);
                } catch (SAXException e) {
                    // Falls through
                }
                reader.setContentHandler(handler);

                // Start pushing SAX events
                reader.parse(input);
            } finally {
                if (!userReader) {
                    _readerManager.releaseXMLReader(reader);
                }
            }
        } else if (source instanceof StAXSource) {
            final StAXSource staxSource = (StAXSource)source;
            StAXEvent2SAX staxevent2sax = null;
            StAXStream2SAX staxStream2SAX = null; 
            if (staxSource.getXMLEventReader() != null) {
                final XMLEventReader xmlEventReader = staxSource.getXMLEventReader();
                staxevent2sax = new StAXEvent2SAX(xmlEventReader);
                staxevent2sax.setContentHandler(handler);
                staxevent2sax.parse();
                handler.flushPending();
            } else if (staxSource.getXMLStreamReader() != null) {
                final XMLStreamReader xmlStreamReader = staxSource.getXMLStreamReader();
                staxStream2SAX = new StAXStream2SAX(xmlStreamReader);
                staxStream2SAX.setContentHandler(handler);
                staxStream2SAX.parse();
                handler.flushPending();
            }
        } else if (source instanceof DOMSource) {
            final DOMSource domsrc = (DOMSource) source;
            new DOM2TO(domsrc.getNode(), handler).parse();
        } else if (source instanceof XSLTCSource) {
            final DOM dom = ((XSLTCSource) source).getDOM(null, _translet);
            ((SAXImpl)dom).copy(handler);
        } else {
            ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_SOURCE_ERR);
            throw new TransformerException(err.toString());
        }
    
private booleanvalidOutputProperty(java.lang.String name)
Verifies if a given output property name is a property defined in the JAXP 1.1 / TrAX spec

	return (name.equals(OutputKeys.ENCODING) ||
		name.equals(OutputKeys.METHOD) ||
		name.equals(OutputKeys.INDENT) ||
		name.equals(OutputKeys.DOCTYPE_PUBLIC) ||
		name.equals(OutputKeys.DOCTYPE_SYSTEM) ||
		name.equals(OutputKeys.CDATA_SECTION_ELEMENTS) ||
		name.equals(OutputKeys.MEDIA_TYPE) ||
		name.equals(OutputKeys.OMIT_XML_DECLARATION)   ||
		name.equals(OutputKeys.STANDALONE) ||
		name.equals(OutputKeys.VERSION) ||
		name.charAt(0) == '{");
    
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()));
        }