KickJava   Java API By Example, From Geeks To Geeks.

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


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

19
20 package com.sun.org.apache.xalan.internal.xsltc.compiler;
21
22 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
23 import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE;
24 import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL;
25 import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;
26 import com.sun.org.apache.bcel.internal.generic.InstructionList;
27 import com.sun.org.apache.bcel.internal.generic.NEW;
28 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
29 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
30 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.NodeSetType;
31 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.NodeType;
32 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ReferenceType;
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
36 /**
37  * @author Jacek Ambroziak
38  * @author Santiago Pericas-Geertsen
39  */

40 final class FilterParentPath extends Expression {
41
42     private Expression _filterExpr;
43     private Expression _path;
44     private boolean _hasDescendantAxis = false;
45
46     public FilterParentPath(Expression filterExpr, Expression path) {
47     (_path = path).setParent(this);
48     (_filterExpr = filterExpr).setParent(this);
49     }
50         
51     public void setParser(Parser parser) {
52     super.setParser(parser);
53     _filterExpr.setParser(parser);
54     _path.setParser(parser);
55     }
56     
57     public String JavaDoc toString() {
58     return "FilterParentPath(" + _filterExpr + ", " + _path + ')';
59     }
60
61     public void setDescendantAxis() {
62     _hasDescendantAxis = true;
63     }
64
65     /**
66      * Type check a FilterParentPath. If the filter is not a node-set add a
67      * cast to node-set only if it is of reference type. This type coercion is
68      * needed for expressions like $x/LINE where $x is a parameter reference.
69      */

70     public Type typeCheck(SymbolTable stable) throws TypeCheckError {
71     final Type ftype = _filterExpr.typeCheck(stable);
72     if (ftype instanceof NodeSetType == false) {
73         if (ftype instanceof ReferenceType) {
74         _filterExpr = new CastExpr(_filterExpr, Type.NodeSet);
75         }
76         /*
77         else if (ftype instanceof ResultTreeType) {
78         _filterExpr = new CastExpr(_filterExpr, Type.NodeSet);
79         }
80         */

81         else if (ftype instanceof NodeType) {
82         _filterExpr = new CastExpr(_filterExpr, Type.NodeSet);
83         }
84         else {
85         throw new TypeCheckError(this);
86         }
87     }
88
89     // Wrap single node path in a node set
90
final Type ptype = _path.typeCheck(stable);
91     if (!(ptype instanceof NodeSetType)) {
92         _path = new CastExpr(_path, Type.NodeSet);
93     }
94
95     return _type = Type.NodeSet;
96     }
97     
98     public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
99     final ConstantPoolGen cpg = classGen.getConstantPool();
100     final InstructionList il = methodGen.getInstructionList();
101     // Create new StepIterator
102
final int initSI = cpg.addMethodref(STEP_ITERATOR_CLASS,
103                         "<init>",
104                         "("
105                         +NODE_ITERATOR_SIG
106                         +NODE_ITERATOR_SIG
107                         +")V");
108     il.append(new NEW(cpg.addClass(STEP_ITERATOR_CLASS)));
109     il.append(DUP);
110
111     // Recursively compile 2 iterators
112
_filterExpr.translate(classGen, methodGen);
113     _path.translate(classGen, methodGen);
114
115     // Initialize StepIterator with iterators from the stack
116
il.append(new INVOKESPECIAL(initSI));
117
118     // This is a special case for the //* path with or without predicates
119
if (_hasDescendantAxis) {
120         final int incl = cpg.addMethodref(NODE_ITERATOR_BASE,
121                           "includeSelf",
122                           "()" + NODE_ITERATOR_SIG);
123         il.append(new INVOKEVIRTUAL(incl));
124     }
125
126     if (!(getParent() instanceof RelativeLocationPath) &&
127         !(getParent() instanceof FilterParentPath)) {
128         final int order = cpg.addInterfaceMethodref(DOM_INTF,
129                             ORDER_ITERATOR,
130                             ORDER_ITERATOR_SIG);
131         il.append(methodGen.loadDOM());
132         il.append(SWAP);
133         il.append(methodGen.loadContextNode());
134         il.append(new INVOKEINTERFACE(order, 3));
135     }
136     }
137 }
138
Popular Tags