FileDocCategorySizeDatePackage
CallTemplate.javaAPI DocJava SE 5 API8909Fri Aug 26 14:55:34 BST 2005com.sun.org.apache.xalan.internal.xsltc.compiler

CallTemplate

public final class CallTemplate extends Instruction
author
Jacek Ambroziak
author
Santiago Pericas-Geertsen
author
Erwin Bolwidt

Fields Summary
private QName
_name
Name of template to call.
private Object[]
_parameters
The array of effective parameters in this CallTemplate. An object in this array can be either a WithParam or a Param if no WithParam exists for a particular parameter.
private Template
_calleeTemplate
The corresponding template which this CallTemplate calls.
Constructors Summary
Methods Summary
private voidbuildParameterList()
Build the list of effective parameters in this CallTemplate. The parameters of the called template are put into the array first. Then we visit the WithParam children of this CallTemplate and replace the Param with a corresponding WithParam having the same name.

   	
    	// Put the parameters from the called template into the array first.
    	// This is to ensure the order of the parameters.
    	Vector defaultParams = _calleeTemplate.getParameters();
    	int numParams = defaultParams.size();
    	_parameters = new Object[numParams];
    	for (int i = 0; i < numParams; i++) {
    	    _parameters[i] = defaultParams.elementAt(i);
    	}
    		    	
    	// Replace a Param with a WithParam if they have the same name.
    	int count = elementCount();
    	for (int i = 0; i < count; i++) {
    	    Object node = elementAt(i);
            
            // Ignore if not WithParam
    	    if (node instanceof WithParam) {
    	    	WithParam withParam = (WithParam)node;
    	    	QName name = withParam.getName();
                
                // Search for a Param with the same name
    	    	for (int k = 0; k < numParams; k++) {
    	    	    Object object = _parameters[k];
    	    	    if (object instanceof Param 
    	    	        && ((Param)object).getName() == name) {
    	    	        withParam.setDoParameterOptimization(true);
    	    	        _parameters[k] = withParam;
    	    	        break;
    	    	    }
    	    	    else if (object instanceof WithParam 
    	    	        && ((WithParam)object).getName() == name) {
    	    	        withParam.setDoParameterOptimization(true);
    	    	        _parameters[k] = withParam;    	    	        
    	    	        break;
    	    	    }
    	    	}    	    	
    	    }
    	}
     
public voiddisplay(int indent)

    
        
	indent(indent);
	System.out.print("CallTemplate");
	Util.println(" name " + _name);
	displayContents(indent + IndentIncrement);
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.TemplategetCalleeTemplate()
Return the simple named template which this CallTemplate calls. Return false if there is no matched template or the matched template is not a simple named template.

    	Stylesheet stylesheet = getXSLTC().getStylesheet();
    	Vector templates = stylesheet.getAllValidTemplates();
        
    	int size = templates.size();
    	for (int i = 0; i < size; i++) {
    	    Template t = (Template)templates.elementAt(i);
    	    if (t.getName() == _name && t.isSimpleNamedTemplate()) {
    	    	return t;
    	    }
    	}
    	return null;
    
public booleanhasWithParams()

	return elementCount() > 0;
    
public voidparseContents(com.sun.org.apache.xalan.internal.xsltc.compiler.Parser parser)

        final String name = getAttribute("name");
        if (name.length() > 0) {
            if (!XMLChar.isValidQName(name)) {
                ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, name, this);
                parser.reportError(Constants.ERROR, err);           
            }                
            _name = parser.getQNameIgnoreDefaultNs(name);
        }
        else {
            reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "name");		
        }
	parseChildren(parser);
    
public voidtranslate(com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator classGen, com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator methodGen)

	final Stylesheet stylesheet = classGen.getStylesheet();
	final ConstantPoolGen cpg = classGen.getConstantPool();
	final InstructionList il = methodGen.getInstructionList();

        // If there are Params in the stylesheet or WithParams in this call?
	if (stylesheet.hasLocalParams() || hasContents()) {
	    _calleeTemplate = getCalleeTemplate();
	    
	    // Build the parameter list if the called template is simple named
	    if (_calleeTemplate != null) {
	    	buildParameterList();
	    }
	    // This is only needed when the called template is not
	    // a simple named template.
	    else {
	        // Push parameter frame
	        final int push = cpg.addMethodref(TRANSLET_CLASS, 
					          PUSH_PARAM_FRAME,
					          PUSH_PARAM_FRAME_SIG);
	        il.append(classGen.loadTranslet());
	        il.append(new INVOKEVIRTUAL(push));
	        translateContents(classGen, methodGen);
	    }
	}

        // Generate a valid Java method name
	final String className = stylesheet.getClassName();
        String methodName = Util.escape(_name.toString());

        // Load standard arguments
	il.append(classGen.loadTranslet());
	il.append(methodGen.loadDOM());
	il.append(methodGen.loadIterator());
	il.append(methodGen.loadHandler());
	il.append(methodGen.loadCurrentNode());
        
        // Initialize prefix of method signature
	StringBuffer methodSig = new StringBuffer("(" + DOM_INTF_SIG 
            + NODE_ITERATOR_SIG + TRANSLET_OUTPUT_SIG + NODE_SIG);
	
        // If calling a simply named template, push actual arguments
	if (_calleeTemplate != null) {
	    Vector calleeParams = _calleeTemplate.getParameters();
	    int numParams = _parameters.length;
	    
	    for (int i = 0; i < numParams; i++) {
	        SyntaxTreeNode node = (SyntaxTreeNode)_parameters[i];
                methodSig.append(OBJECT_SIG);   // append Object to signature
                
                // Push 'null' if Param to indicate no actual parameter specified
                if (node instanceof Param) {
                    il.append(ACONST_NULL);
                }
                else {  // translate WithParam
                    node.translate(classGen, methodGen);
                }
            }
        }

        // Complete signature and generate invokevirtual call
	methodSig.append(")V");
	il.append(new INVOKEVIRTUAL(cpg.addMethodref(className,
						     methodName,
						     methodSig.toString())));
	
	// Do not need to call Translet.popParamFrame() if we are
	// calling a simple named template.
	if (_calleeTemplate == null && (stylesheet.hasLocalParams() || hasContents())) {
	    // Pop parameter frame
	    final int pop = cpg.addMethodref(TRANSLET_CLASS,
					     POP_PARAM_FRAME,
					     POP_PARAM_FRAME_SIG);
	    il.append(classGen.loadTranslet());
	    il.append(new INVOKEVIRTUAL(pop));
	}
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypetypeCheck(com.sun.org.apache.xalan.internal.xsltc.compiler.SymbolTable stable)
Verify that a template with this name exists.

	final Template template = stable.lookupTemplate(_name);
	if (template != null) {
	    typeCheckContents(stable);
	}
	else {
	    ErrorMsg err = new ErrorMsg(ErrorMsg.TEMPLATE_UNDEF_ERR,_name,this);
	    throw new TypeCheckError(err);
	}
	return Type.Void;