1 16 19 20 package com.sun.org.apache.xalan.internal.xsltc.compiler; 21 22 import com.sun.org.apache.bcel.internal.generic.ALOAD; 23 import com.sun.org.apache.bcel.internal.generic.ASTORE; 24 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; 25 import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; 26 import com.sun.org.apache.bcel.internal.generic.InstructionList; 27 import com.sun.org.apache.bcel.internal.generic.LocalVariableGen; 28 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; 29 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; 30 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator; 31 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; 32 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; 33 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; 34 import com.sun.org.apache.xml.internal.utils.XMLChar; 35 36 import java.util.Vector ; 37 38 43 final class CallTemplate extends Instruction { 44 45 48 private QName _name; 49 50 55 private Object [] _parameters = null; 56 57 60 private Template _calleeTemplate = null; 61 62 public void display(int indent) { 63 indent(indent); 64 System.out.print("CallTemplate"); 65 Util.println(" name " + _name); 66 displayContents(indent + IndentIncrement); 67 } 68 69 public boolean hasWithParams() { 70 return elementCount() > 0; 71 } 72 73 public void parseContents(Parser parser) { 74 final String name = getAttribute("name"); 75 if (name.length() > 0) { 76 if (!XMLChar.isValidQName(name)) { 77 ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, name, this); 78 parser.reportError(Constants.ERROR, err); 79 } 80 _name = parser.getQNameIgnoreDefaultNs(name); 81 } 82 else { 83 reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "name"); 84 } 85 parseChildren(parser); 86 } 87 88 91 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 92 final Template template = stable.lookupTemplate(_name); 93 if (template != null) { 94 typeCheckContents(stable); 95 } 96 else { 97 ErrorMsg err = new ErrorMsg(ErrorMsg.TEMPLATE_UNDEF_ERR,_name,this); 98 throw new TypeCheckError(err); 99 } 100 return Type.Void; 101 } 102 103 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 104 final Stylesheet stylesheet = classGen.getStylesheet(); 105 final ConstantPoolGen cpg = classGen.getConstantPool(); 106 final InstructionList il = methodGen.getInstructionList(); 107 108 if (stylesheet.hasLocalParams() || hasContents()) { 110 _calleeTemplate = getCalleeTemplate(); 111 112 if (_calleeTemplate != null) { 114 buildParameterList(); 115 } 116 else { 119 final int push = cpg.addMethodref(TRANSLET_CLASS, 121 PUSH_PARAM_FRAME, 122 PUSH_PARAM_FRAME_SIG); 123 il.append(classGen.loadTranslet()); 124 il.append(new INVOKEVIRTUAL(push)); 125 translateContents(classGen, methodGen); 126 } 127 } 128 129 final String className = stylesheet.getClassName(); 131 String methodName = Util.escape(_name.toString()); 132 133 il.append(classGen.loadTranslet()); 135 il.append(methodGen.loadDOM()); 136 il.append(methodGen.loadIterator()); 137 il.append(methodGen.loadHandler()); 138 il.append(methodGen.loadCurrentNode()); 139 140 StringBuffer methodSig = new StringBuffer ("(" + DOM_INTF_SIG 142 + NODE_ITERATOR_SIG + TRANSLET_OUTPUT_SIG + NODE_SIG); 143 144 if (_calleeTemplate != null) { 146 Vector calleeParams = _calleeTemplate.getParameters(); 147 int numParams = _parameters.length; 148 149 for (int i = 0; i < numParams; i++) { 150 SyntaxTreeNode node = (SyntaxTreeNode)_parameters[i]; 151 methodSig.append(OBJECT_SIG); 153 if (node instanceof Param) { 155 il.append(ACONST_NULL); 156 } 157 else { node.translate(classGen, methodGen); 159 } 160 } 161 } 162 163 methodSig.append(")V"); 165 il.append(new INVOKEVIRTUAL(cpg.addMethodref(className, 166 methodName, 167 methodSig.toString()))); 168 169 if (_calleeTemplate == null && (stylesheet.hasLocalParams() || hasContents())) { 172 final int pop = cpg.addMethodref(TRANSLET_CLASS, 174 POP_PARAM_FRAME, 175 POP_PARAM_FRAME_SIG); 176 il.append(classGen.loadTranslet()); 177 il.append(new INVOKEVIRTUAL(pop)); 178 } 179 } 180 181 186 public Template getCalleeTemplate() { 187 Template foundTemplate 188 = getXSLTC().getParser().getSymbolTable().lookupTemplate(_name); 189 190 return foundTemplate.isSimpleNamedTemplate() ? foundTemplate : null; 191 } 192 193 199 private void buildParameterList() { 200 Vector defaultParams = _calleeTemplate.getParameters(); 203 int numParams = defaultParams.size(); 204 _parameters = new Object [numParams]; 205 for (int i = 0; i < numParams; i++) { 206 _parameters[i] = defaultParams.elementAt(i); 207 } 208 209 int count = elementCount(); 211 for (int i = 0; i < count; i++) { 212 Object node = elementAt(i); 213 214 if (node instanceof WithParam) { 216 WithParam withParam = (WithParam)node; 217 QName name = withParam.getName(); 218 219 for (int k = 0; k < numParams; k++) { 221 Object object = _parameters[k]; 222 if (object instanceof Param 223 && ((Param)object).getName() == name) { 224 withParam.setDoParameterOptimization(true); 225 _parameters[k] = withParam; 226 break; 227 } 228 else if (object instanceof WithParam 229 && ((WithParam)object).getName() == name) { 230 withParam.setDoParameterOptimization(true); 231 _parameters[k] = withParam; 232 break; 233 } 234 } 235 } 236 } 237 } 238 } 239 240 | Popular Tags |