FileDocCategorySizeDatePackage
TemplatesImpl.javaAPI DocJava SE 5 API11834Fri Aug 26 14:55:42 BST 2005com.sun.org.apache.xalan.internal.xsltc.trax

TemplatesImpl

public final class TemplatesImpl extends Object implements Serializable, Templates
author
Morten Jorgensen
author
G. Todd Millerj
author
Jochen Cordes
author
Santiago Pericas-Geertsen

Fields Summary
private static String
ABSTRACT_TRANSLET
Name of the superclass of all translets. This is needed to determine which, among all classes comprising a translet, is the main one.
private String
_name
Name of the main class or default name if unknown.
private byte[]
_bytecodes
Contains the actual class definition for the translet class and any auxiliary classes.
private Class[]
_class
Contains the translet class definition(s). These are created when this Templates is created or when it is read back from disk.
private int
_transletIndex
The index of the main translet class in the arrays _class[] and _bytecodes.
private com.sun.org.apache.xalan.internal.xsltc.runtime.Hashtable
_auxClasses
Contains the list of auxiliary class definitions.
private Properties
_outputProperties
Output properties of this translet.
private int
_indentNumber
Number of spaces to add for output indentation.
private transient URIResolver
_uriResolver
This URIResolver is passed to all Transformers. Declaring it transient to fix bug 22438
private transient ThreadLocal
_sdom
Cache the DTM for the stylesheet in a thread local variable, which is used by the document('') function. Use ThreadLocal because a DTM cannot be shared between multiple threads. Declaring it transient to fix bug 22438
private transient TransformerFactoryImpl
_tfactory
A reference to the transformer factory that this templates object belongs to.
Constructors Summary
protected TemplatesImpl(byte[] bytecodes, String transletName, Properties outputProperties, int indentNumber, TransformerFactoryImpl tfactory)
Create an XSLTC template object from the bytecodes. The bytecodes for the translet and auxiliary classes, plus the name of the main translet class, must be supplied.

	_bytecodes = bytecodes;
	_name      = transletName;
	_outputProperties = outputProperties;
	_indentNumber = indentNumber;
	_tfactory = tfactory;
    
protected TemplatesImpl(Class[] transletClasses, String transletName, Properties outputProperties, int indentNumber, TransformerFactoryImpl tfactory)
Create an XSLTC template object from the translet class definition(s).

	_class     = transletClasses;
	_name      = transletName;
	_transletIndex = 0;
	_outputProperties = outputProperties;
	_indentNumber = indentNumber;
	_tfactory = tfactory;
    
public TemplatesImpl()
Need for de-serialization, see readObject().

 
Methods Summary
private voiddefineTransletClasses()
Defines the translet class and auxiliary classes. Returns a reference to the Class object that defines the main class


	if (_bytecodes == null) {
	    ErrorMsg err = new ErrorMsg(ErrorMsg.NO_TRANSLET_CLASS_ERR);
	    throw new TransformerConfigurationException(err.toString());
	}

        TransletClassLoader loader = (TransletClassLoader)
            AccessController.doPrivileged(new PrivilegedAction() {
                public Object run() {
                    return new TransletClassLoader(ObjectFactory.findClassLoader());
                }
            });

	try {
	    final int classCount = _bytecodes.length;
	    _class = new Class[classCount];

	    if (classCount > 1) {
	        _auxClasses = new Hashtable();
	    }

	    for (int i = 0; i < classCount; i++) {
		_class[i] = loader.defineClass(_bytecodes[i]);
		final Class superClass = _class[i].getSuperclass();

		// Check if this is the main class
		if (superClass.getName().equals(ABSTRACT_TRANSLET)) {
		    _transletIndex = i;
		}
		else {
		    _auxClasses.put(_class[i].getName(), _class[i]);
		}
	    }

	    if (_transletIndex < 0) {
		ErrorMsg err= new ErrorMsg(ErrorMsg.NO_MAIN_TRANSLET_ERR, _name);
		throw new TransformerConfigurationException(err.toString());
	    }
	}
	catch (ClassFormatError e) {
	    ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_CLASS_ERR, _name);
	    throw new TransformerConfigurationException(err.toString());
	}
	catch (LinkageError e) {
	    ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_OBJECT_ERR, _name);
	    throw new TransformerConfigurationException(err.toString());
	}
    
public synchronized java.util.PropertiesgetOutputProperties()
Implements JAXP's Templates.getOutputProperties(). We need to instanciate a translet to get the output settings, so we might as well just instanciate a Transformer and use its implementation of this method.

 
	try {
	    return newTransformer().getOutputProperties();
	}
	catch (TransformerConfigurationException e) {
	    return null;
	}
    
public com.sun.org.apache.xalan.internal.xsltc.DOMgetStylesheetDOM()
Return the thread local copy of the stylesheet DOM.

    	return (DOM)_sdom.get();
    
public synchronized byte[][]getTransletBytecodes()
Returns the translet bytecodes stored in this template

	return _bytecodes;
    
public synchronized java.lang.Class[]getTransletClasses()
Returns the translet bytecodes stored in this template

	try {
	    if (_class == null) defineTransletClasses();
	}
	catch (TransformerConfigurationException e) {
	    // Falls through
	}
	return _class;
    
public synchronized intgetTransletIndex()
Returns the index of the main class in array of bytecodes

	try {
	    if (_class == null) defineTransletClasses();
	}
	catch (TransformerConfigurationException e) {
	    // Falls through
	}
	return _transletIndex;
    
private com.sun.org.apache.xalan.internal.xsltc.TransletgetTransletInstance()
This method generates an instance of the translet class that is wrapped inside this Template. The translet instance will later be wrapped inside a Transformer object.

	try {
	    if (_name == null) return null;

	    if (_class == null) defineTransletClasses();

	    // The translet needs to keep a reference to all its auxiliary 
	    // class to prevent the GC from collecting them
	    AbstractTranslet translet = (AbstractTranslet) _class[_transletIndex].newInstance();
            translet.postInitialization();
	    translet.setTemplates(this);
	    if (_auxClasses != null) {
	        translet.setAuxiliaryClasses(_auxClasses);
	    }
	    
	    return translet;
	}
	catch (InstantiationException e) {
	    ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_OBJECT_ERR, _name);
	    throw new TransformerConfigurationException(err.toString());
	}
	catch (IllegalAccessException e) {
	    ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_OBJECT_ERR, _name);
	    throw new TransformerConfigurationException(err.toString());
	}
    
protected synchronized java.lang.StringgetTransletName()
Returns the name of the main translet class stored in this template

	return _name;
    
public synchronized javax.xml.transform.TransformernewTransformer()
Implements JAXP's Templates.newTransformer()

throws
TransformerConfigurationException

	TransformerImpl transformer;

	transformer = new TransformerImpl(getTransletInstance(), _outputProperties,
	    _indentNumber, _tfactory);
	
	if (_uriResolver != null) {
	    transformer.setURIResolver(_uriResolver);
	}
	return transformer;
    
private voidreadObject(java.io.ObjectInputStream is)
Overrides the default readObject implementation since we decided it would be cleaner not to serialize the entire tranformer factory. [ ref bugzilla 12317 ] We need to check if the user defined class for URIResolver also implemented Serializable if yes then we need to deserialize the URIResolver Fix for bugzilla bug 22438

	is.defaultReadObject();
        if (is.readBoolean()) {
            _uriResolver = (URIResolver) is.readObject();
        }

	_tfactory = new TransformerFactoryImpl();
    
public voidsetStylesheetDOM(com.sun.org.apache.xalan.internal.xsltc.DOM sdom)
Set the thread local copy of the stylesheet DOM.

    	_sdom.set(sdom);
    
protected synchronized voidsetTransletBytecodes(byte[][] bytecodes)
The TransformerFactory must pass us the translet bytecodes using this method before we can create any translet instances

	_bytecodes = bytecodes;
    
protected synchronized voidsetTransletName(java.lang.String name)
The TransformerFactory should call this method to set the translet name

	_name = name;
    
public synchronized voidsetURIResolver(javax.xml.transform.URIResolver resolver)
Store URIResolver needed for Transformers.

	_uriResolver = resolver;
    
private voidwriteObject(java.io.ObjectOutputStream os)
This is to fix bugzilla bug 22438 If the user defined class implements URIResolver and Serializable then we want it to get serialized

        os.defaultWriteObject();
        if (_uriResolver instanceof Serializable) {
            os.writeBoolean(true);
            os.writeObject((Serializable) _uriResolver);
        }
        else {
            os.writeBoolean(false);
        }