1. /*
  2. * Copyright 2001-2004 The Apache Software Foundation.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /*
  17. * $Id: ApplyImports.java,v 1.13 2004/02/16 22:24:29 minchau Exp $
  18. */
  19. package com.sun.org.apache.xalan.internal.xsltc.compiler;
  20. import java.util.Enumeration;
  21. import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
  22. import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL;
  23. import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;
  24. import com.sun.org.apache.bcel.internal.generic.InstructionList;
  25. import com.sun.org.apache.bcel.internal.generic.NEW;
  26. import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
  27. import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
  28. import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
  29. import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
  30. import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util;
  31. /**
  32. * @author Morten Jorgensen
  33. */
  34. final class ApplyImports extends Instruction {
  35. private QName _modeName;
  36. private String _functionName;
  37. private int _precedence;
  38. public void display(int indent) {
  39. indent(indent);
  40. Util.println("ApplyTemplates");
  41. indent(indent + IndentIncrement);
  42. if (_modeName != null) {
  43. indent(indent + IndentIncrement);
  44. Util.println("mode " + _modeName);
  45. }
  46. }
  47. /**
  48. * Returns true if this <xsl:apply-imports/> element has parameters
  49. */
  50. public boolean hasWithParams() {
  51. return hasContents();
  52. }
  53. /**
  54. * Determine the lowest import precedence for any stylesheet imported
  55. * or included by the stylesheet in which this <xsl:apply-imports/>
  56. * element occured. The templates that are imported by the stylesheet in
  57. * which this element occured will all have higher import precedence than
  58. * the integer returned by this method.
  59. */
  60. private int getMinPrecedence(int max) {
  61. Stylesheet stylesheet = getStylesheet();
  62. Stylesheet root = getParser().getTopLevelStylesheet();
  63. int min = max;
  64. Enumeration templates = root.getContents().elements();
  65. while (templates.hasMoreElements()) {
  66. SyntaxTreeNode child = (SyntaxTreeNode)templates.nextElement();
  67. if (child instanceof Template) {
  68. Stylesheet curr = child.getStylesheet();
  69. while ((curr != null) && (curr != stylesheet)) {
  70. if (curr._importedFrom != null)
  71. curr = curr._importedFrom;
  72. else if (curr._includedFrom != null)
  73. curr = curr._includedFrom;
  74. else
  75. curr = null;
  76. }
  77. if (curr == stylesheet) {
  78. int prec = child.getStylesheet().getImportPrecedence();
  79. if (prec < min) min = prec;
  80. }
  81. }
  82. }
  83. return (min);
  84. }
  85. /**
  86. * Parse the attributes and contents of an <xsl:apply-imports/> element.
  87. */
  88. public void parseContents(Parser parser) {
  89. // Indicate to the top-level stylesheet that all templates must be
  90. // compiled into separate methods.
  91. Stylesheet stylesheet = getStylesheet();
  92. stylesheet.setTemplateInlining(false);
  93. // Get the mode we are currently in (might not be any)
  94. Template template = getTemplate();
  95. _modeName = template.getModeName();
  96. _precedence = template.getImportPrecedence();
  97. // Get the method name for <xsl:apply-imports/> in this mode
  98. stylesheet = parser.getTopLevelStylesheet();
  99. // Get the [min,max> precedence of all templates imported under the
  100. // current stylesheet
  101. final int maxPrecedence = _precedence;
  102. final int minPrecedence = getMinPrecedence(maxPrecedence);
  103. final Mode mode = stylesheet.getMode(_modeName);
  104. _functionName = mode.functionName(minPrecedence, maxPrecedence);
  105. parseChildren(parser); // with-params
  106. }
  107. /**
  108. * Type-check the attributes/contents of an <xsl:apply-imports/> element.
  109. */
  110. public Type typeCheck(SymbolTable stable) throws TypeCheckError {
  111. typeCheckContents(stable); // with-params
  112. return Type.Void;
  113. }
  114. /**
  115. * Translate call-template. A parameter frame is pushed only if
  116. * some template in the stylesheet uses parameters.
  117. */
  118. public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
  119. final Stylesheet stylesheet = classGen.getStylesheet();
  120. final ConstantPoolGen cpg = classGen.getConstantPool();
  121. final InstructionList il = methodGen.getInstructionList();
  122. final int current = methodGen.getLocalIndex("current");
  123. // Push the arguments that are passed to applyTemplates()
  124. il.append(classGen.loadTranslet());
  125. il.append(methodGen.loadDOM());
  126. // Wrap the current node inside an iterator
  127. int init = cpg.addMethodref(SINGLETON_ITERATOR,
  128. "<init>", "("+NODE_SIG+")V");
  129. il.append(new NEW(cpg.addClass(SINGLETON_ITERATOR)));
  130. il.append(DUP);
  131. il.append(methodGen.loadCurrentNode());
  132. il.append(new INVOKESPECIAL(init));
  133. il.append(methodGen.loadHandler());
  134. // Construct the translet class-name and the signature of the method
  135. final String className = classGen.getStylesheet().getClassName();
  136. final String signature = classGen.getApplyTemplatesSig();
  137. final int applyTemplates = cpg.addMethodref(className,
  138. _functionName,
  139. signature);
  140. il.append(new INVOKEVIRTUAL(applyTemplates));
  141. }
  142. }