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: IdKeyPattern.java,v 1.10 2004/02/16 22:24:29 minchau Exp $
  18. */
  19. package com.sun.org.apache.xalan.internal.xsltc.compiler;
  20. import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
  21. import com.sun.org.apache.bcel.internal.generic.GOTO;
  22. import com.sun.org.apache.bcel.internal.generic.IFNE;
  23. import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE;
  24. import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;
  25. import com.sun.org.apache.bcel.internal.generic.InstructionList;
  26. import com.sun.org.apache.bcel.internal.generic.PUSH;
  27. import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
  28. import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
  29. import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
  30. import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
  31. /**
  32. * @author Jacek Ambroziak
  33. * @author Santiago Pericas-Geertsen
  34. */
  35. abstract class IdKeyPattern extends LocationPathPattern {
  36. protected RelativePathPattern _left = null;;
  37. private String _index = null;
  38. private String _value = null;;
  39. public IdKeyPattern(String index, String value) {
  40. _index = index;
  41. _value = value;
  42. }
  43. public String getIndexName() {
  44. return(_index);
  45. }
  46. public Type typeCheck(SymbolTable stable) throws TypeCheckError {
  47. return Type.NodeSet;
  48. }
  49. public boolean isWildcard() {
  50. return false;
  51. }
  52. public void setLeft(RelativePathPattern left) {
  53. _left = left;
  54. }
  55. public StepPattern getKernelPattern() {
  56. return(null);
  57. }
  58. public void reduceKernelPattern() { }
  59. public String toString() {
  60. return "id/keyPattern(" + _index + ", " + _value + ')';
  61. }
  62. /**
  63. * This method is called when the constructor is compiled in
  64. * Stylesheet.compileConstructor() and not as the syntax tree is traversed.
  65. */
  66. public void translate(ClassGenerator classGen,
  67. MethodGenerator methodGen) {
  68. final ConstantPoolGen cpg = classGen.getConstantPool();
  69. final InstructionList il = methodGen.getInstructionList();
  70. // Returns the KeyIndex object of a given name
  71. final int getKeyIndex = cpg.addMethodref(TRANSLET_CLASS,
  72. "getKeyIndex",
  73. "(Ljava/lang/String;)"+
  74. KEY_INDEX_SIG);
  75. // Initialises a KeyIndex to return nodes with specific values
  76. final int lookupId = cpg.addMethodref(KEY_INDEX_CLASS,
  77. "containsID",
  78. "(ILjava/lang/Object;)I");
  79. final int lookupKey = cpg.addMethodref(KEY_INDEX_CLASS,
  80. "containsKey",
  81. "(ILjava/lang/Object;)I");
  82. final int getNodeIdent = cpg.addInterfaceMethodref(DOM_INTF,
  83. "getNodeIdent",
  84. "(I)"+NODE_SIG);
  85. // Call getKeyIndex in AbstractTranslet with the name of the key
  86. // to get the index for this key (which is also a node iterator).
  87. il.append(classGen.loadTranslet());
  88. il.append(new PUSH(cpg,_index));
  89. il.append(new INVOKEVIRTUAL(getKeyIndex));
  90. // Now use the value in the second argument to determine what nodes
  91. // the iterator should return.
  92. il.append(SWAP);
  93. il.append(new PUSH(cpg,_value));
  94. if (this instanceof IdPattern)
  95. {
  96. il.append(SWAP);
  97. il.append(methodGen.loadDOM());
  98. il.append(SWAP);
  99. il.append(new INVOKEINTERFACE(getNodeIdent, 2));
  100. il.append(SWAP);
  101. il.append(new INVOKEVIRTUAL(lookupId));
  102. }
  103. else
  104. {
  105. il.append(SWAP);
  106. il.append(methodGen.loadDOM());
  107. il.append(SWAP);
  108. il.append(new INVOKEINTERFACE(getNodeIdent, 2));
  109. il.append(SWAP);
  110. il.append(new INVOKEVIRTUAL(lookupKey));
  111. }
  112. _trueList.add(il.append(new IFNE(null)));
  113. _falseList.add(il.append(new GOTO(null)));
  114. }
  115. }