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