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: ApplyImports.java,v 1.2.4.1 2005/09/13 12:22:02 pvedula Exp $ 22 */ 23 24 package com.sun.org.apache.xalan.internal.xsltc.compiler; 25 26 import java.util.Enumeration; 27 28 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; 29 import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL; 30 import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; 31 import com.sun.org.apache.bcel.internal.generic.InstructionList; 32 import com.sun.org.apache.bcel.internal.generic.NEW; 33 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; 34 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator; 35 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; 36 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; 37 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; 38 39 final class ApplyImports extends Instruction { 40 41 private QName _modeName; 42 private int _precedence; 43 44 public void display(int indent) { 45 indent(indent); 46 Util.println("ApplyTemplates"); 47 indent(indent + IndentIncrement); 48 if (_modeName != null) { 49 indent(indent + IndentIncrement); 50 Util.println("mode " + _modeName); 51 } 52 } 53 54 /** 55 * Returns true if this <xsl:apply-imports/> element has parameters 56 */ 57 public boolean hasWithParams() { 58 return hasContents(); 59 } 60 61 /** 62 * Determine the lowest import precedence for any stylesheet imported 63 * or included by the stylesheet in which this <xsl:apply-imports/> 64 * element occured. The templates that are imported by the stylesheet in 65 * which this element occured will all have higher import precedence than 66 * the integer returned by this method. 67 */ 68 private int getMinPrecedence(int max) { 69 // Move to root of include tree 70 Stylesheet includeRoot = getStylesheet(); 71 while (includeRoot._includedFrom != null) { 72 includeRoot = includeRoot._includedFrom; 73 } 74 75 return includeRoot.getMinimumDescendantPrecedence(); 76 } 77 78 /** 79 * Parse the attributes and contents of an <xsl:apply-imports/> element. 80 */ 81 public void parseContents(Parser parser) { 82 // Indicate to the top-level stylesheet that all templates must be 83 // compiled into separate methods. 84 Stylesheet stylesheet = getStylesheet(); 85 stylesheet.setTemplateInlining(false); 86 87 // Get the mode we are currently in (might not be any) 88 Template template = getTemplate(); 89 _modeName = template.getModeName(); 90 _precedence = template.getImportPrecedence(); 91 92 // Get the method name for <xsl:apply-imports/> in this mode 93 stylesheet = parser.getTopLevelStylesheet(); 94 95 parseChildren(parser); // with-params 96 } 97 98 /** 99 * Type-check the attributes/contents of an <xsl:apply-imports/> element. 100 */ 101 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 102 typeCheckContents(stable); // with-params 103 return Type.Void; 104 } 105 106 /** 107 * Translate call-template. A parameter frame is pushed only if 108 * some template in the stylesheet uses parameters. 109 */ 110 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 111 final Stylesheet stylesheet = classGen.getStylesheet(); 112 final ConstantPoolGen cpg = classGen.getConstantPool(); 113 final InstructionList il = methodGen.getInstructionList(); 114 final int current = methodGen.getLocalIndex("current"); 115 116 // Push the arguments that are passed to applyTemplates() 117 il.append(classGen.loadTranslet()); 118 il.append(methodGen.loadDOM()); 119 il.append(methodGen.loadIterator()); 120 il.append(methodGen.loadHandler()); 121 il.append(methodGen.loadCurrentNode()); 122 123 // Push a new parameter frame in case imported template might expect 124 // parameters. The apply-imports has nothing that it can pass. 125 if (stylesheet.hasLocalParams()) { 126 il.append(classGen.loadTranslet()); 127 final int pushFrame = cpg.addMethodref(TRANSLET_CLASS, 128 PUSH_PARAM_FRAME, 129 PUSH_PARAM_FRAME_SIG); 130 il.append(new INVOKEVIRTUAL(pushFrame)); 131 } 132 133 // Get the [min,max> precedence of all templates imported under the 134 // current stylesheet 135 final int maxPrecedence = _precedence; 136 final int minPrecedence = getMinPrecedence(maxPrecedence); 137 final Mode mode = stylesheet.getMode(_modeName); 138 139 // Get name of appropriate apply-templates function for this 140 // xsl:apply-imports instruction 141 String functionName = mode.functionName(minPrecedence, maxPrecedence); 142 143 // Construct the translet class-name and the signature of the method 144 final String className = classGen.getStylesheet().getClassName(); 145 final String signature = classGen.getApplyTemplatesSigForImport(); 146 final int applyTemplates = cpg.addMethodref(className, 147 functionName, 148 signature); 149 il.append(new INVOKEVIRTUAL(applyTemplates)); 150 151 // Pop any parameter frame that was pushed above. 152 if (stylesheet.hasLocalParams()) { 153 il.append(classGen.loadTranslet()); 154 final int pushFrame = cpg.addMethodref(TRANSLET_CLASS, 155 POP_PARAM_FRAME, 156 POP_PARAM_FRAME_SIG); 157 il.append(new INVOKEVIRTUAL(pushFrame)); 158 } 159 } 160 161 }