1 16 19 20 package org.apache.xalan.xsltc.compiler; 21 22 import org.apache.bcel.generic.ALOAD; 23 import org.apache.bcel.generic.ASTORE; 24 import org.apache.bcel.generic.ConstantPoolGen; 25 import org.apache.bcel.generic.INVOKEVIRTUAL; 26 import org.apache.bcel.generic.InstructionList; 27 import org.apache.bcel.generic.LocalVariableGen; 28 import org.apache.xalan.xsltc.compiler.util.ClassGenerator; 29 import org.apache.xalan.xsltc.compiler.util.ErrorMsg; 30 import org.apache.xalan.xsltc.compiler.util.MethodGenerator; 31 import org.apache.xalan.xsltc.compiler.util.Type; 32 import org.apache.xalan.xsltc.compiler.util.TypeCheckError; 33 import org.apache.xalan.xsltc.compiler.util.Util; 34 import org.apache.xml.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 Stylesheet stylesheet = getXSLTC().getStylesheet(); 188 Vector templates = stylesheet.getAllValidTemplates(); 189 190 int size = templates.size(); 191 for (int i = 0; i < size; i++) { 192 Template t = (Template)templates.elementAt(i); 193 if (t.getName() == _name && t.isSimpleNamedTemplate()) { 194 return t; 195 } 196 } 197 return null; 198 } 199 200 206 private void buildParameterList() { 207 Vector defaultParams = _calleeTemplate.getParameters(); 210 int numParams = defaultParams.size(); 211 _parameters = new Object [numParams]; 212 for (int i = 0; i < numParams; i++) { 213 _parameters[i] = defaultParams.elementAt(i); 214 } 215 216 int count = elementCount(); 218 for (int i = 0; i < count; i++) { 219 Object node = elementAt(i); 220 221 if (node instanceof WithParam) { 223 WithParam withParam = (WithParam)node; 224 QName name = withParam.getName(); 225 226 for (int k = 0; k < numParams; k++) { 228 Object object = _parameters[k]; 229 if (object instanceof Param 230 && ((Param)object).getName() == name) { 231 withParam.setDoParameterOptimization(true); 232 _parameters[k] = withParam; 233 break; 234 } 235 else if (object instanceof WithParam 236 && ((WithParam)object).getName() == name) { 237 withParam.setDoParameterOptimization(true); 238 _parameters[k] = withParam; 239 break; 240 } 241 } 242 } 243 } 244 } 245 } 246 247 | Popular Tags |