1 16 19 20 package com.sun.org.apache.xalan.internal.xsltc.compiler; 21 22 import java.util.Vector ; 23 import com.sun.org.apache.bcel.internal.generic.BranchHandle; 24 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; 25 import com.sun.org.apache.bcel.internal.generic.GOTO; 26 import com.sun.org.apache.bcel.internal.generic.IFEQ; 27 import com.sun.org.apache.bcel.internal.generic.IFGE; 28 import com.sun.org.apache.bcel.internal.generic.IFGT; 29 import com.sun.org.apache.bcel.internal.generic.ILOAD; 30 import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE; 31 import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; 32 import com.sun.org.apache.bcel.internal.generic.ISTORE; 33 import com.sun.org.apache.bcel.internal.generic.InstructionHandle; 34 import com.sun.org.apache.bcel.internal.generic.InstructionList; 35 import com.sun.org.apache.bcel.internal.generic.LocalVariableGen; 36 import com.sun.org.apache.bcel.internal.generic.PUSH; 37 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; 38 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; 39 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator; 40 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.NodeSetType; 41 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.StringType; 42 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; 43 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; 44 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; 45 import com.sun.org.apache.xalan.internal.xsltc.dom.Axis; 46 import com.sun.org.apache.xml.internal.utils.XMLChar; 47 48 52 final class Key extends TopLevelElement { 53 54 57 private QName _name; 58 59 62 private Pattern _match; 63 64 67 private Expression _use; 68 69 72 private Type _useType; 73 74 78 public void parseContents(Parser parser) { 79 80 final String name = getAttribute("name"); 82 if (!XMLChar.isValidQName(name)){ 83 ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, name, this); 84 parser.reportError(Constants.ERROR, err); 85 } 86 _name = parser.getQNameIgnoreDefaultNs(name); 88 getSymbolTable().addKey(_name, this); 89 _match = parser.parsePattern(this, "match", null); 90 _use = parser.parseExpression(this, "use", null); 91 92 if (_name == null) { 94 reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "name"); 95 return; 96 } 97 if (_match.isDummy()) { 98 reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "match"); 99 return; 100 } 101 if (_use.isDummy()) { 102 reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "use"); 103 return; 104 } 105 } 106 107 111 public String getName() { 112 return _name.toString(); 113 } 114 115 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 116 _match.typeCheck(stable); 118 119 _useType = _use.typeCheck(stable); 121 if (_useType instanceof StringType == false && 122 _useType instanceof NodeSetType == false) 123 { 124 _use = new CastExpr(_use, Type.String); 125 } 126 127 return Type.Void; 128 } 129 130 135 public void traverseNodeSet(ClassGenerator classGen, 136 MethodGenerator methodGen, 137 int buildKeyIndex) { 138 final ConstantPoolGen cpg = classGen.getConstantPool(); 139 final InstructionList il = methodGen.getInstructionList(); 140 141 final int getNodeValue = cpg.addInterfaceMethodref(DOM_INTF, 143 GET_NODE_VALUE, 144 "(I)"+STRING_SIG); 145 146 final int getNodeIdent = cpg.addInterfaceMethodref(DOM_INTF, 147 "getNodeIdent", 148 "(I)"+NODE_SIG); 149 150 final int keyDom = cpg.addMethodref(TRANSLET_CLASS, 152 "setKeyIndexDom", 153 "("+STRING_SIG+DOM_INTF_SIG+")V"); 154 155 156 final LocalVariableGen parentNode = 160 methodGen.addLocalVariable("parentNode", 161 Util.getJCRefType("I"), 162 il.getEnd(), null); 163 164 il.append(new ISTORE(parentNode.getIndex())); 166 il.append(methodGen.loadDOM()); 167 il.append(new ILOAD(parentNode.getIndex())); 168 il.append(new INVOKEINTERFACE(getNodeIdent, 2)); 169 il.append(new ISTORE(parentNode.getIndex())); 170 171 il.append(methodGen.loadCurrentNode()); 173 il.append(methodGen.loadIterator()); 174 175 _use.translate(classGen, methodGen); 177 _use.startIterator(classGen, methodGen); 178 il.append(methodGen.storeIterator()); 179 180 final BranchHandle nextNode = il.append(new GOTO(null)); 181 final InstructionHandle loop = il.append(NOP); 182 183 il.append(classGen.loadTranslet()); 185 il.append(new PUSH(cpg, _name.toString())); 186 il.append(new ILOAD(parentNode.getIndex())); 187 188 il.append(methodGen.loadDOM()); 190 il.append(methodGen.loadCurrentNode()); 191 il.append(new INVOKEINTERFACE(getNodeValue, 2)); 192 193 il.append(new INVOKEVIRTUAL(buildKeyIndex)); 195 196 il.append(classGen.loadTranslet()); 197 il.append(new PUSH(cpg, getName())); 198 il.append(methodGen.loadDOM()); 199 il.append(new INVOKEVIRTUAL(keyDom)); 200 201 nextNode.setTarget(il.append(methodGen.loadIterator())); 202 il.append(methodGen.nextNode()); 203 204 il.append(DUP); 205 il.append(methodGen.storeCurrentNode()); 206 il.append(new IFGE(loop)); 208 il.append(methodGen.storeIterator()); 210 il.append(methodGen.storeCurrentNode()); 211 } 212 213 217 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 218 219 final ConstantPoolGen cpg = classGen.getConstantPool(); 220 final InstructionList il = methodGen.getInstructionList(); 221 final int current = methodGen.getLocalIndex("current"); 222 223 final int key = cpg.addMethodref(TRANSLET_CLASS, 225 "buildKeyIndex", 226 "("+STRING_SIG+"I"+OBJECT_SIG+")V"); 227 228 final int keyDom = cpg.addMethodref(TRANSLET_CLASS, 230 "setKeyIndexDom", 231 "("+STRING_SIG+DOM_INTF_SIG+")V"); 232 233 final int getNodeIdent = cpg.addInterfaceMethodref(DOM_INTF, 234 "getNodeIdent", 235 "(I)"+NODE_SIG); 236 237 final int git = cpg.addInterfaceMethodref(DOM_INTF, 239 "getAxisIterator", 240 "(I)"+NODE_ITERATOR_SIG); 241 242 il.append(methodGen.loadCurrentNode()); 243 il.append(methodGen.loadIterator()); 244 245 il.append(methodGen.loadDOM()); 247 il.append(new PUSH(cpg,Axis.DESCENDANT)); 248 il.append(new INVOKEINTERFACE(git, 2)); 249 250 il.append(methodGen.loadCurrentNode()); 252 il.append(methodGen.setStartNode()); 253 il.append(methodGen.storeIterator()); 254 255 final BranchHandle nextNode = il.append(new GOTO(null)); 257 final InstructionHandle loop = il.append(NOP); 258 259 il.append(methodGen.loadCurrentNode()); 261 _match.translate(classGen, methodGen); 262 _match.synthesize(classGen, methodGen); final BranchHandle skipNode = il.append(new IFEQ(null)); 264 265 if (_useType instanceof NodeSetType) { 267 il.append(methodGen.loadCurrentNode()); 269 traverseNodeSet(classGen, methodGen, key); 270 } 271 else { 272 il.append(classGen.loadTranslet()); 273 il.append(DUP); 274 il.append(new PUSH(cpg, _name.toString())); 275 il.append(DUP_X1); 276 il.append(methodGen.loadCurrentNode()); 277 _use.translate(classGen, methodGen); 278 il.append(SWAP); 279 il.append(methodGen.loadDOM()); 280 il.append(SWAP); 281 il.append(new INVOKEINTERFACE(getNodeIdent, 2)); 282 il.append(SWAP); 283 il.append(new INVOKEVIRTUAL(key)); 284 285 il.append(methodGen.loadDOM()); 286 il.append(new INVOKEVIRTUAL(keyDom)); 287 } 288 289 final InstructionHandle skip = il.append(NOP); 291 292 il.append(methodGen.loadIterator()); 293 il.append(methodGen.nextNode()); 294 il.append(DUP); 295 il.append(methodGen.storeCurrentNode()); 296 il.append(new IFGT(loop)); 297 298 il.append(methodGen.storeIterator()); 300 il.append(methodGen.storeCurrentNode()); 301 302 nextNode.setTarget(skip); 303 skipNode.setTarget(skip); 304 } 305 } 306 | Popular Tags |