KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xalan > internal > xsltc > compiler > FilterExpr


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: FilterExpr.java,v 1.11 2004/02/16 22:24:29 minchau Exp $
18  */

19
20 package com.sun.org.apache.xalan.internal.xsltc.compiler;
21
22 import java.util.Vector JavaDoc;
23
24 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
25 import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE;
26 import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL;
27 import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC;
28 import com.sun.org.apache.bcel.internal.generic.InstructionList;
29 import com.sun.org.apache.bcel.internal.generic.NEW;
30 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
31 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
32 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.NodeSetType;
33 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ReferenceType;
34 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
35 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
36
37 /**
38  * @author Jacek Ambroziak
39  * @author Santiago Pericas-Geertsen
40  * @author Morten Jorgensen
41  */

42 class FilterExpr extends Expression {
43     
44     /**
45      * Primary expression of this filter. I.e., 'e' in '(e)[p1]...[pn]'.
46      */

47     private Expression _primary;
48     
49     /**
50      * Array of predicates in '(e)[p1]...[pn]'.
51      */

52     private final Vector JavaDoc _predicates;
53
54     public FilterExpr(Expression primary, Vector JavaDoc predicates) {
55     _primary = primary;
56     _predicates = predicates;
57     primary.setParent(this);
58     }
59
60     protected Expression getExpr() {
61     if (_primary instanceof CastExpr)
62         return ((CastExpr)_primary).getExpr();
63     else
64         return _primary;
65     }
66
67     public void setParser(Parser parser) {
68     super.setParser(parser);
69     _primary.setParser(parser);
70     if (_predicates != null) {
71         final int n = _predicates.size();
72         for (int i = 0; i < n; i++) {
73         final Expression exp = (Expression)_predicates.elementAt(i);
74         exp.setParser(parser);
75         exp.setParent(this);
76         }
77     }
78     }
79     
80     public String JavaDoc toString() {
81     return "filter-expr(" + _primary + ", " + _predicates + ")";
82     }
83
84     /**
85      * Type check a FilterParentPath. If the filter is not a node-set add a
86      * cast to node-set only if it is of reference type. This type coercion
87      * is needed for expressions like $x where $x is a parameter reference.
88      * All optimizations are turned off before type checking underlying
89      * predicates.
90      */

91     public Type typeCheck(SymbolTable stable) throws TypeCheckError {
92     Type ptype = _primary.typeCheck(stable);
93
94     if (ptype instanceof NodeSetType == false) {
95         if (ptype instanceof ReferenceType) {
96         _primary = new CastExpr(_primary, Type.NodeSet);
97         }
98         else {
99         throw new TypeCheckError(this);
100         }
101     }
102
103         // Type check predicates and turn all optimizations off
104
int n = _predicates.size();
105     for (int i = 0; i < n; i++) {
106         Predicate pred = (Predicate) _predicates.elementAt(i);
107             pred.dontOptimize();
108         pred.typeCheck(stable);
109     }
110     return _type = Type.NodeSet;
111     }
112     
113     /**
114      * Translate a filter expression by pushing the appropriate iterator
115      * onto the stack.
116      */

117     public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
118     if (_predicates.size() > 0) {
119         translatePredicates(classGen, methodGen);
120     }
121     else {
122         _primary.translate(classGen, methodGen);
123     }
124     }
125
126     /**
127      * Translate a sequence of predicates. Each predicate is translated
128      * by constructing an instance of <code>CurrentNodeListIterator</code>
129      * which is initialized from another iterator (recursive call), a
130      * filter and a closure (call to translate on the predicate) and "this".
131      */

132     public void translatePredicates(ClassGenerator classGen,
133                     MethodGenerator methodGen) {
134     final ConstantPoolGen cpg = classGen.getConstantPool();
135     final InstructionList il = methodGen.getInstructionList();
136
137         // If not predicates left, translate primary expression
138
if (_predicates.size() == 0) {
139         translate(classGen, methodGen);
140     }
141     else {
142             // Translate predicates from right to left
143
final int initCNLI = cpg.addMethodref(CURRENT_NODE_LIST_ITERATOR,
144                           "<init>",
145                           "("+NODE_ITERATOR_SIG+"Z"+
146                           CURRENT_NODE_LIST_FILTER_SIG +
147                           NODE_SIG+TRANSLET_SIG+")V");
148
149         Predicate predicate = (Predicate)_predicates.lastElement();
150         _predicates.remove(predicate);
151
152             // Create a CurrentNodeListIterator
153
il.append(new NEW(cpg.addClass(CURRENT_NODE_LIST_ITERATOR)));
154             il.append(DUP);
155             
156             // Translate the rest of the predicates from right to left
157
translatePredicates(classGen, methodGen);
158             
159             // Initialize CurrentNodeListIterator
160
il.append(ICONST_1);
161             predicate.translate(classGen, methodGen);
162             il.append(methodGen.loadCurrentNode());
163             il.append(classGen.loadTranslet());
164             il.append(new INVOKESPECIAL(initCNLI));
165     }
166     }
167 }
168
Popular Tags