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