KickJava   Java API By Example, From Geeks To Geeks.

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


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: NodeType.java,v 1.12 2004/02/16 22:26:45 minchau Exp $
18  */

19
20 package com.sun.org.apache.xalan.internal.xsltc.compiler.util;
21
22 import com.sun.org.apache.bcel.internal.generic.BranchHandle;
23 import com.sun.org.apache.bcel.internal.generic.CHECKCAST;
24 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
25 import com.sun.org.apache.bcel.internal.generic.GETFIELD;
26 import com.sun.org.apache.bcel.internal.generic.GOTO;
27 import com.sun.org.apache.bcel.internal.generic.IFEQ;
28 import com.sun.org.apache.bcel.internal.generic.ILOAD;
29 import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE;
30 import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL;
31 import com.sun.org.apache.bcel.internal.generic.ISTORE;
32 import com.sun.org.apache.bcel.internal.generic.Instruction;
33 import com.sun.org.apache.bcel.internal.generic.InstructionList;
34 import com.sun.org.apache.bcel.internal.generic.NEW;
35 import com.sun.org.apache.bcel.internal.generic.PUSH;
36 import com.sun.org.apache.xalan.internal.xsltc.compiler.Constants;
37 import com.sun.org.apache.xalan.internal.xsltc.compiler.FlowList;
38 import com.sun.org.apache.xalan.internal.xsltc.compiler.NodeTest;
39
40 /**
41  * @author Jacek Ambroziak
42  * @author Santiago Pericas-Geertsen
43  */

44 public final class NodeType extends Type {
45     private final int _type;
46
47     protected NodeType() {
48     this(NodeTest.ANODE);
49     }
50
51     protected NodeType(int type) {
52     _type = type;
53     }
54
55     public int getType() {
56     return _type;
57     }
58
59     public String JavaDoc toString() {
60     return "node-type";
61     }
62
63     public boolean identicalTo(Type other) {
64     return other instanceof NodeType;
65     }
66
67     public int hashCode() {
68     return _type;
69     }
70
71     public String JavaDoc toSignature() {
72     return "I";
73     }
74
75     public com.sun.org.apache.bcel.internal.generic.Type toJCType() {
76     return com.sun.org.apache.bcel.internal.generic.Type.INT;
77     }
78
79     /**
80      * Translates a node into an object of internal type <code>type</code>.
81      * The translation to int is undefined since nodes are always converted
82      * to reals in arithmetic expressions.
83      *
84      * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
85      */

86     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
87                 Type type) {
88     if (type == Type.String) {
89         translateTo(classGen, methodGen, (StringType) type);
90     }
91     else if (type == Type.Boolean) {
92         translateTo(classGen, methodGen, (BooleanType) type);
93     }
94     else if (type == Type.Real) {
95         translateTo(classGen, methodGen, (RealType) type);
96     }
97     else if (type == Type.NodeSet) {
98         translateTo(classGen, methodGen, (NodeSetType) type);
99     }
100     else if (type == Type.Reference) {
101         translateTo(classGen, methodGen, (ReferenceType) type);
102     }
103     else if (type == Type.Object) {
104         translateTo(classGen, methodGen, (ObjectType) type);
105     }
106     else {
107         ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
108                     toString(), type.toString());
109         classGen.getParser().reportError(Constants.FATAL, err);
110     }
111     }
112
113     /**
114      * Expects a node on the stack and pushes its string value.
115      *
116      * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
117      */

118     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
119                 StringType type) {
120     final ConstantPoolGen cpg = classGen.getConstantPool();
121     final InstructionList il = methodGen.getInstructionList();
122
123     switch (_type) {
124     case NodeTest.ROOT:
125     case NodeTest.ELEMENT:
126         il.append(methodGen.loadDOM());
127         il.append(SWAP); // dom ref must be below node index
128
int index = cpg.addInterfaceMethodref(DOM_INTF,
129                           GET_ELEMENT_VALUE,
130                           GET_ELEMENT_VALUE_SIG);
131         il.append(new INVOKEINTERFACE(index, 2));
132         break;
133
134     case NodeTest.ANODE:
135     case NodeTest.COMMENT:
136     case NodeTest.ATTRIBUTE:
137     case NodeTest.PI:
138         il.append(methodGen.loadDOM());
139         il.append(SWAP); // dom ref must be below node index
140
index = cpg.addInterfaceMethodref(DOM_INTF,
141                           GET_NODE_VALUE,
142                           GET_NODE_VALUE_SIG);
143         il.append(new INVOKEINTERFACE(index, 2));
144         break;
145         
146     default:
147         ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
148                     toString(), type.toString());
149         classGen.getParser().reportError(Constants.FATAL, err);
150         break;
151     }
152     }
153
154     /**
155      * Translates a node into a synthesized boolean.
156      * If the expression is "@attr",
157      * then "true" is pushed iff "attr" is an attribute of the current node.
158      * If the expression is ".", the result is always "true".
159      *
160      * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
161      */

162     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
163                 BooleanType type) {
164     final InstructionList il = methodGen.getInstructionList();
165     FlowList falsel = translateToDesynthesized(classGen, methodGen, type);
166     il.append(ICONST_1);
167     final BranchHandle truec = il.append(new GOTO(null));
168     falsel.backPatch(il.append(ICONST_0));
169     truec.setTarget(il.append(NOP));
170     }
171
172     /**
173      * Expects a node on the stack and pushes a real.
174      * First the node is converted to string, and from string to real.
175      *
176      * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
177      */

178     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
179                 RealType type) {
180     translateTo(classGen, methodGen, Type.String);
181     Type.String.translateTo(classGen, methodGen, Type.Real);
182     }
183
184     /**
185      * Expects a node on the stack and pushes a singleton node-set. Singleton
186      * iterators are already started after construction.
187      *
188      * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
189      */

190     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
191                 NodeSetType type) {
192     ConstantPoolGen cpg = classGen.getConstantPool();
193     InstructionList il = methodGen.getInstructionList();
194
195     // Create a new instance of SingletonIterator
196
il.append(new NEW(cpg.addClass(SINGLETON_ITERATOR)));
197     il.append(DUP_X1);
198     il.append(SWAP);
199     final int init = cpg.addMethodref(SINGLETON_ITERATOR, "<init>",
200                       "(" + NODE_SIG +")V");
201     il.append(new INVOKESPECIAL(init));
202     }
203
204     /**
205      * Subsume Node into ObjectType.
206      *
207      * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
208      */

209     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
210                 ObjectType type) {
211         methodGen.getInstructionList().append(NOP);
212     }
213
214     /**
215      * Translates a node into a non-synthesized boolean. It does not push a
216      * 0 or a 1 but instead returns branchhandle list to be appended to the
217      * false list.
218      *
219      * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateToDesynthesized
220      */

221     public FlowList translateToDesynthesized(ClassGenerator classGen,
222                          MethodGenerator methodGen,
223                          BooleanType type) {
224     final InstructionList il = methodGen.getInstructionList();
225     return new FlowList(il.append(new IFEQ(null)));
226     }
227
228     /**
229      * Expects a node on the stack and pushes a boxed node. Boxed nodes
230      * are represented by an instance of <code>com.sun.org.apache.xalan.internal.xsltc.dom.Node</code>.
231      *
232      * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
233      */

234     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
235                 ReferenceType type) {
236     final ConstantPoolGen cpg = classGen.getConstantPool();
237     final InstructionList il = methodGen.getInstructionList();
238     il.append(new NEW(cpg.addClass(RUNTIME_NODE_CLASS)));
239     il.append(DUP_X1);
240     il.append(SWAP);
241     il.append(new PUSH(cpg, _type));
242     il.append(new INVOKESPECIAL(cpg.addMethodref(RUNTIME_NODE_CLASS,
243                              "<init>", "(II)V")));
244     }
245
246     /**
247      * Translates a node into the Java type denoted by <code>clazz</code>.
248      * Expects a node on the stack and pushes an object of the appropriate
249      * type after coercion.
250      */

251     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
252                 Class JavaDoc clazz) {
253     final ConstantPoolGen cpg = classGen.getConstantPool();
254     final InstructionList il = methodGen.getInstructionList();
255
256         String JavaDoc className = clazz.getName();
257         if (className.equals("java.lang.String")) {
258            translateTo(classGen, methodGen, Type.String);
259            return;
260         }
261
262     il.append(methodGen.loadDOM());
263     il.append(SWAP); // dom ref must be below node index
264

265         if (className.equals("org.w3c.dom.Node") ||
266             className.equals("java.lang.Object")) {
267         int index = cpg.addInterfaceMethodref(DOM_INTF,
268                           MAKE_NODE,
269                           MAKE_NODE_SIG);
270         il.append(new INVOKEINTERFACE(index, 2));
271     }
272     else if (className.equals("org.w3c.dom.NodeList")) {
273         int index = cpg.addInterfaceMethodref(DOM_INTF,
274                           MAKE_NODE_LIST,
275                           MAKE_NODE_LIST_SIG);
276         il.append(new INVOKEINTERFACE(index, 2));
277     }
278     else {
279         ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
280                     toString(), className);
281         classGen.getParser().reportError(Constants.FATAL, err);
282     }
283     }
284
285     /**
286      * Translates an object of this type to its boxed representation.
287      */

288     public void translateBox(ClassGenerator classGen,
289                  MethodGenerator methodGen) {
290     translateTo(classGen, methodGen, Type.Reference);
291     }
292
293     /**
294      * Translates an object of this type to its unboxed representation.
295      */

296     public void translateUnBox(ClassGenerator classGen,
297                    MethodGenerator methodGen) {
298     final ConstantPoolGen cpg = classGen.getConstantPool();
299     final InstructionList il = methodGen.getInstructionList();
300     il.append(new CHECKCAST(cpg.addClass(RUNTIME_NODE_CLASS)));
301     il.append(new GETFIELD(cpg.addFieldref(RUNTIME_NODE_CLASS,
302                            NODE_FIELD,
303                            NODE_FIELD_SIG)));
304     }
305
306     /**
307      * Returns the class name of an internal type's external representation.
308      */

309     public String JavaDoc getClassName() {
310     return(RUNTIME_NODE_CLASS);
311     }
312
313     public Instruction LOAD(int slot) {
314     return new ILOAD(slot);
315     }
316     
317     public Instruction STORE(int slot) {
318     return new ISTORE(slot);
319     }
320 }
321
322
Popular Tags