KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xalan > xsltc > compiler > UnionPathExpr


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: UnionPathExpr.java,v 1.10 2004/02/16 22:25:10 minchau Exp $
18  */

19
20 package org.apache.xalan.xsltc.compiler;
21
22 import java.util.Vector JavaDoc;
23
24 import org.apache.bcel.generic.ConstantPoolGen;
25 import org.apache.bcel.generic.INVOKEINTERFACE;
26 import org.apache.bcel.generic.INVOKESPECIAL;
27 import org.apache.bcel.generic.INVOKEVIRTUAL;
28 import org.apache.bcel.generic.InstructionList;
29 import org.apache.bcel.generic.NEW;
30 import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
31 import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
32 import org.apache.xalan.xsltc.compiler.util.Type;
33 import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
34 import org.apache.xalan.xsltc.dom.Axis;
35 import org.apache.xml.dtm.DTM;
36
37 /**
38  * @author Jacek Ambroziak
39  * @author Santiago Pericas-Geertsen
40  */

41 final class UnionPathExpr extends Expression {
42
43     private final Expression _pathExpr;
44     private final Expression _rest;
45     private boolean _reverse = false;
46
47     // linearization for top level UnionPathExprs
48
private Expression[] _components;
49     
50     public UnionPathExpr(Expression pathExpr, Expression rest) {
51     _pathExpr = pathExpr;
52     _rest = rest;
53     }
54
55     public void setParser(Parser parser) {
56     super.setParser(parser);
57     // find all expressions in this Union
58
final Vector JavaDoc components = new Vector JavaDoc();
59     flatten(components);
60     final int size = components.size();
61     _components = (Expression[])components.toArray(new Expression[size]);
62     for (int i = 0; i < size; i++) {
63         _components[i].setParser(parser);
64         _components[i].setParent(this);
65         if (_components[i] instanceof Step) {
66         final Step step = (Step)_components[i];
67         final int axis = step.getAxis();
68         final int type = step.getNodeType();
69         // Put attribute iterators first
70
if ((axis == Axis.ATTRIBUTE) || (type == DTM.ATTRIBUTE_NODE)) {
71             _components[i] = _components[0];
72             _components[0] = step;
73         }
74         // Check if the union contains a reverse iterator
75
if (Axis.isReverse[axis]) _reverse = true;
76         }
77     }
78     // No need to reverse anything if another expression lies on top of this
79
if (getParent() instanceof Expression) _reverse = false;
80     }
81     
82     public Type typeCheck(SymbolTable stable) throws TypeCheckError {
83     final int length = _components.length;
84     for (int i = 0; i < length; i++) {
85         if (_components[i].typeCheck(stable) != Type.NodeSet) {
86         _components[i] = new CastExpr(_components[i], Type.NodeSet);
87         }
88     }
89     return _type = Type.NodeSet;
90     }
91
92     public String JavaDoc toString() {
93     return "union(" + _pathExpr + ", " + _rest + ')';
94     }
95     
96     private void flatten(Vector JavaDoc components) {
97     components.addElement(_pathExpr);
98     if (_rest != null) {
99         if (_rest instanceof UnionPathExpr) {
100         ((UnionPathExpr)_rest).flatten(components);
101         }
102         else {
103         components.addElement(_rest);
104         }
105     }
106     }
107
108     public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
109     final ConstantPoolGen cpg = classGen.getConstantPool();
110     final InstructionList il = methodGen.getInstructionList();
111
112     final int init = cpg.addMethodref(UNION_ITERATOR_CLASS,
113                       "<init>",
114                       "("+DOM_INTF_SIG+")V");
115     final int iter = cpg.addMethodref(UNION_ITERATOR_CLASS,
116                       ADD_ITERATOR,
117                       ADD_ITERATOR_SIG);
118
119     // Create the UnionIterator and leave it on the stack
120
il.append(new NEW(cpg.addClass(UNION_ITERATOR_CLASS)));
121     il.append(DUP);
122     il.append(methodGen.loadDOM());
123     il.append(new INVOKESPECIAL(init));
124
125     // Add the various iterators to the UnionIterator
126
final int length = _components.length;
127     for (int i = 0; i < length; i++) {
128         _components[i].translate(classGen, methodGen);
129         il.append(new INVOKEVIRTUAL(iter));
130     }
131
132     // Order the iterator only if strictly needed
133
if (_reverse) {
134         final int order = cpg.addInterfaceMethodref(DOM_INTF,
135                             ORDER_ITERATOR,
136                             ORDER_ITERATOR_SIG);
137         il.append(methodGen.loadDOM());
138         il.append(SWAP);
139         il.append(methodGen.loadContextNode());
140         il.append(new INVOKEINTERFACE(order, 3));
141
142     }
143     }
144 }
145
Popular Tags