1 16 19 20 package org.apache.xalan.xsltc.compiler; 21 22 import java.util.Vector ; 23 24 import org.apache.bcel.generic.CHECKCAST; 25 import org.apache.bcel.generic.ConstantPoolGen; 26 import org.apache.bcel.generic.ICONST; 27 import org.apache.bcel.generic.INVOKEINTERFACE; 28 import org.apache.bcel.generic.INVOKESPECIAL; 29 import org.apache.bcel.generic.InstructionList; 30 import org.apache.bcel.generic.NEW; 31 import org.apache.bcel.generic.PUSH; 32 import org.apache.xalan.xsltc.DOM; 33 import org.apache.xalan.xsltc.compiler.util.ClassGenerator; 34 import org.apache.xalan.xsltc.compiler.util.MethodGenerator; 35 import org.apache.xalan.xsltc.compiler.util.Type; 36 import org.apache.xalan.xsltc.compiler.util.TypeCheckError; 37 import org.apache.xalan.xsltc.dom.Axis; 38 import org.apache.xml.dtm.DTM; 39 40 45 final class Step extends RelativeLocationPath { 46 47 50 private int _axis; 51 52 55 private Vector _predicates; 56 57 62 private boolean _hadPredicates = false; 63 64 67 private int _nodeType; 68 69 public Step(int axis, int nodeType, Vector predicates) { 70 _axis = axis; 71 _nodeType = nodeType; 72 _predicates = predicates; 73 } 74 75 78 public void setParser(Parser parser) { 79 super.setParser(parser); 80 if (_predicates != null) { 81 final int n = _predicates.size(); 82 for (int i = 0; i < n; i++) { 83 final Predicate exp = (Predicate)_predicates.elementAt(i); 84 exp.setParser(parser); 85 exp.setParent(this); 86 } 87 } 88 } 89 90 93 public int getAxis() { 94 return _axis; 95 } 96 97 100 public void setAxis(int axis) { 101 _axis = axis; 102 } 103 104 107 public int getNodeType() { 108 return _nodeType; 109 } 110 111 114 public Vector getPredicates() { 115 return _predicates; 116 } 117 118 121 public void addPredicates(Vector predicates) { 122 if (_predicates == null) { 123 _predicates = predicates; 124 } 125 else { 126 _predicates.addAll(predicates); 127 } 128 } 129 130 135 private boolean hasParentPattern() { 136 final SyntaxTreeNode parent = getParent(); 137 return (parent instanceof ParentPattern || 138 parent instanceof ParentLocationPath || 139 parent instanceof UnionPathExpr || 140 parent instanceof FilterParentPath); 141 } 142 143 146 private boolean hasPredicates() { 147 return _predicates != null && _predicates.size() > 0; 148 } 149 150 153 private boolean isPredicate() { 154 SyntaxTreeNode parent = this; 155 while (parent != null) { 156 parent = parent.getParent(); 157 if (parent instanceof Predicate) return true; 158 } 159 return false; 160 } 161 162 165 public boolean isAbbreviatedDot() { 166 return _nodeType == NodeTest.ANODE && _axis == Axis.SELF; 167 } 168 169 170 173 public boolean isAbbreviatedDDot() { 174 return _nodeType == NodeTest.ANODE && _axis == Axis.PARENT; 175 } 176 177 182 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 183 184 _hadPredicates = hasPredicates(); 187 188 if (isAbbreviatedDot()) { 192 _type = (hasParentPattern() || hasPredicates() ) ? 193 Type.NodeSet : Type.Node; 194 } 195 else { 196 _type = Type.NodeSet; 197 } 198 199 if (_predicates != null) { 201 final int n = _predicates.size(); 202 for (int i = 0; i < n; i++) { 203 final Expression pred = (Expression)_predicates.elementAt(i); 204 pred.typeCheck(stable); 205 } 206 } 207 208 return _type; 210 } 211 212 219 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 220 final ConstantPoolGen cpg = classGen.getConstantPool(); 221 final InstructionList il = methodGen.getInstructionList(); 222 223 if (hasPredicates()) { 224 translatePredicates(classGen, methodGen); 225 } else { 226 int star = 0; 227 String name = null; 228 final XSLTC xsltc = getParser().getXSLTC(); 229 230 if (_nodeType >= DTM.NTYPES) { 231 final Vector ni = xsltc.getNamesIndex(); 232 233 name = (String )ni.elementAt(_nodeType-DTM.NTYPES); 234 star = name.lastIndexOf('*'); 235 } 236 237 if (_axis == Axis.ATTRIBUTE && _nodeType != NodeTest.ATTRIBUTE 240 && _nodeType != NodeTest.ANODE && !hasParentPattern() 241 && star == 0) 242 { 243 int iter = cpg.addInterfaceMethodref(DOM_INTF, 244 "getTypedAxisIterator", 245 "(II)"+NODE_ITERATOR_SIG); 246 il.append(methodGen.loadDOM()); 247 il.append(new PUSH(cpg, Axis.ATTRIBUTE)); 248 il.append(new PUSH(cpg, _nodeType)); 249 il.append(new INVOKEINTERFACE(iter, 3)); 250 return; 251 } 252 253 if (isAbbreviatedDot()) { 255 if (_type == Type.Node) { 256 il.append(methodGen.loadContextNode()); 258 } 259 else { 260 int init = cpg.addMethodref(SINGLETON_ITERATOR, 262 "<init>", "("+NODE_SIG+")V"); 263 il.append(new NEW(cpg.addClass(SINGLETON_ITERATOR))); 264 il.append(DUP); 265 il.append(methodGen.loadContextNode()); 266 il.append(new INVOKESPECIAL(init)); 267 } 268 return; 269 } 270 271 SyntaxTreeNode parent = getParent(); 273 if ((parent instanceof ParentLocationPath) && 274 (parent.getParent() instanceof ParentLocationPath)) { 275 if ((_nodeType == NodeTest.ELEMENT) && (!_hadPredicates)) { 276 _nodeType = NodeTest.ANODE; 277 } 278 } 279 280 switch (_nodeType) { 282 case NodeTest.ATTRIBUTE: 283 _axis = Axis.ATTRIBUTE; 284 case NodeTest.ANODE: 285 int git = cpg.addInterfaceMethodref(DOM_INTF, 287 "getAxisIterator", 288 "(I)"+NODE_ITERATOR_SIG); 289 il.append(methodGen.loadDOM()); 290 il.append(new PUSH(cpg, _axis)); 291 il.append(new INVOKEINTERFACE(git, 2)); 292 break; 293 default: 294 if (star > 1) { 295 final String namespace; 296 if (_axis == Axis.ATTRIBUTE) 297 namespace = name.substring(0,star-2); 298 else 299 namespace = name.substring(0,star-1); 300 301 final int nsType = xsltc.registerNamespace(namespace); 302 final int ns = cpg.addInterfaceMethodref(DOM_INTF, 303 "getNamespaceAxisIterator", 304 "(II)"+NODE_ITERATOR_SIG); 305 il.append(methodGen.loadDOM()); 306 il.append(new PUSH(cpg, _axis)); 307 il.append(new PUSH(cpg, nsType)); 308 il.append(new INVOKEINTERFACE(ns, 3)); 309 break; 310 } 311 case NodeTest.ELEMENT: 312 final int ty = cpg.addInterfaceMethodref(DOM_INTF, 314 "getTypedAxisIterator", 315 "(II)"+NODE_ITERATOR_SIG); 316 il.append(methodGen.loadDOM()); 318 il.append(new PUSH(cpg, _axis)); 319 il.append(new PUSH(cpg, _nodeType)); 320 il.append(new INVOKEINTERFACE(ty, 3)); 321 322 break; 323 } 324 } 325 } 326 327 328 334 public void translatePredicates(ClassGenerator classGen, 335 MethodGenerator methodGen) { 336 final ConstantPoolGen cpg = classGen.getConstantPool(); 337 final InstructionList il = methodGen.getInstructionList(); 338 339 int idx = 0; 340 341 if (_predicates.size() == 0) { 342 translate(classGen, methodGen); 343 } 344 else { 345 final Predicate predicate = (Predicate)_predicates.lastElement(); 346 _predicates.remove(predicate); 347 348 if (predicate.isNodeValueTest()) { 356 Step step = predicate.getStep(); 357 358 il.append(methodGen.loadDOM()); 359 if (step.isAbbreviatedDot()) { 362 translate(classGen, methodGen); 363 il.append(new ICONST(DOM.RETURN_CURRENT)); 364 } 365 else { 368 ParentLocationPath path = new ParentLocationPath(this,step); 369 try { 370 path.typeCheck(getParser().getSymbolTable()); 371 } 372 catch (TypeCheckError e) { } 373 path.translate(classGen, methodGen); 374 il.append(new ICONST(DOM.RETURN_PARENT)); 375 } 376 predicate.translate(classGen, methodGen); 377 idx = cpg.addInterfaceMethodref(DOM_INTF, 378 GET_NODE_VALUE_ITERATOR, 379 GET_NODE_VALUE_ITERATOR_SIG); 380 il.append(new INVOKEINTERFACE(idx, 5)); 381 } 382 else if (predicate.isNthDescendant()) { 384 il.append(methodGen.loadDOM()); 385 il.append(new ICONST(predicate.getPosType())); 387 predicate.translate(classGen, methodGen); 388 il.append(new ICONST(0)); 389 idx = cpg.addInterfaceMethodref(DOM_INTF, 390 "getNthDescendant", 391 "(IIZ)"+NODE_ITERATOR_SIG); 392 il.append(new INVOKEINTERFACE(idx, 4)); 393 } 394 else if (predicate.isNthPositionFilter()) { 396 idx = cpg.addMethodref(NTH_ITERATOR_CLASS, 397 "<init>", 398 "("+NODE_ITERATOR_SIG+"I)V"); 399 il.append(new NEW(cpg.addClass(NTH_ITERATOR_CLASS))); 400 il.append(DUP); 401 translatePredicates(classGen, methodGen); predicate.translate(classGen, methodGen); 403 il.append(new INVOKESPECIAL(idx)); 404 } 405 else { 406 idx = cpg.addMethodref(CURRENT_NODE_LIST_ITERATOR, 407 "<init>", 408 "(" 409 + NODE_ITERATOR_SIG 410 + CURRENT_NODE_LIST_FILTER_SIG 411 + NODE_SIG 412 + TRANSLET_SIG 413 + ")V"); 414 il.append(new NEW(cpg.addClass(CURRENT_NODE_LIST_ITERATOR))); 416 il.append(DUP); 417 translatePredicates(classGen, methodGen); predicate.translateFilter(classGen, methodGen); 419 420 il.append(methodGen.loadCurrentNode()); 421 il.append(classGen.loadTranslet()); 422 if (classGen.isExternal()) { 423 final String className = classGen.getClassName(); 424 il.append(new CHECKCAST(cpg.addClass(className))); 425 } 426 il.append(new INVOKESPECIAL(idx)); 427 } 428 } 429 } 430 431 434 public String toString() { 435 final StringBuffer buffer = new StringBuffer ("step(\""); 436 buffer.append(Axis.names[_axis]).append("\", ").append(_nodeType); 437 if (_predicates != null) { 438 final int n = _predicates.size(); 439 for (int i = 0; i < n; i++) { 440 final Predicate pred = (Predicate)_predicates.elementAt(i); 441 buffer.append(", ").append(pred.toString()); 442 } 443 } 444 return buffer.append(')').toString(); 445 } 446 } 447 | Popular Tags |