1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Copyright 2001-2004 The Apache Software Foundation. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 /* 21 * $Id: AbsolutePathPattern.java,v 1.2.4.1 2005/09/01 09:17:09 pvedula Exp $ 22 */ 23 24 package com.sun.org.apache.xalan.internal.xsltc.compiler; 25 26 import com.sun.org.apache.bcel.internal.generic.BranchHandle; 27 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; 28 import com.sun.org.apache.bcel.internal.generic.GOTO_W; 29 import com.sun.org.apache.bcel.internal.generic.IF_ICMPEQ; 30 import com.sun.org.apache.bcel.internal.generic.ILOAD; 31 import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE; 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.MethodGenerator; 39 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; 40 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; 41 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; 42 import com.sun.org.apache.xml.internal.dtm.DTM; 43 44 /** 45 * @author Jacek Ambroziak 46 * @author Santiago Pericas-Geertsen 47 */ 48 final class AbsolutePathPattern extends LocationPathPattern { 49 private final RelativePathPattern _left; // may be null 50 51 public AbsolutePathPattern(RelativePathPattern left) { 52 _left = left; 53 if (left != null) { 54 left.setParent(this); 55 } 56 } 57 58 public void setParser(Parser parser) { 59 super.setParser(parser); 60 if (_left != null) 61 _left.setParser(parser); 62 } 63 64 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 65 return _left == null ? Type.Root : _left.typeCheck(stable); 66 } 67 68 public boolean isWildcard() { 69 return false; 70 } 71 72 public StepPattern getKernelPattern() { 73 return _left != null ? _left.getKernelPattern() : null; 74 } 75 76 public void reduceKernelPattern() { 77 _left.reduceKernelPattern(); 78 } 79 80 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 81 final ConstantPoolGen cpg = classGen.getConstantPool(); 82 final InstructionList il = methodGen.getInstructionList(); 83 84 if (_left != null) { 85 if (_left instanceof StepPattern) { 86 final LocalVariableGen local = 87 // absolute path pattern temporary 88 methodGen.addLocalVariable2("apptmp", 89 Util.getJCRefType(NODE_SIG), 90 null); 91 il.append(DUP); 92 local.setStart(il.append(new ISTORE(local.getIndex()))); 93 _left.translate(classGen, methodGen); 94 il.append(methodGen.loadDOM()); 95 local.setEnd(il.append(new ILOAD(local.getIndex()))); 96 methodGen.removeLocalVariable(local); 97 } 98 else { 99 _left.translate(classGen, methodGen); 100 } 101 } 102 103 final int getParent = cpg.addInterfaceMethodref(DOM_INTF, 104 GET_PARENT, 105 GET_PARENT_SIG); 106 final int getType = cpg.addInterfaceMethodref(DOM_INTF, 107 "getExpandedTypeID", 108 "(I)I"); 109 110 InstructionHandle begin = il.append(methodGen.loadDOM()); 111 il.append(SWAP); 112 il.append(new INVOKEINTERFACE(getParent, 2)); 113 if (_left instanceof AncestorPattern) { 114 il.append(methodGen.loadDOM()); 115 il.append(SWAP); 116 } 117 il.append(new INVOKEINTERFACE(getType, 2)); 118 il.append(new PUSH(cpg, DTM.DOCUMENT_NODE)); 119 120 final BranchHandle skip = il.append(new IF_ICMPEQ(null)); 121 _falseList.add(il.append(new GOTO_W(null))); 122 skip.setTarget(il.append(NOP)); 123 124 if (_left != null) { 125 _left.backPatchTrueList(begin); 126 127 /* 128 * If _left is an ancestor pattern, backpatch this pattern's false 129 * list to the loop that searches for more ancestors. 130 */ 131 if (_left instanceof AncestorPattern) { 132 final AncestorPattern ancestor = (AncestorPattern) _left; 133 _falseList.backPatch(ancestor.getLoopHandle()); // clears list 134 } 135 _falseList.append(_left._falseList); 136 } 137 } 138 139 public String toString() { 140 return "absolutePathPattern(" + (_left != null ? _left.toString() : ")"); 141 } 142 }