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