KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xalan > xsltc > compiler > util > NodeSetType


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

19
20 package org.apache.xalan.xsltc.compiler.util;
21
22 import org.apache.bcel.generic.ALOAD;
23 import org.apache.bcel.generic.ASTORE;
24 import org.apache.bcel.generic.BranchHandle;
25 import org.apache.bcel.generic.ConstantPoolGen;
26 import org.apache.bcel.generic.GOTO;
27 import org.apache.bcel.generic.IFLT;
28 import org.apache.bcel.generic.INVOKEINTERFACE;
29 import org.apache.bcel.generic.INVOKESTATIC;
30 import org.apache.bcel.generic.Instruction;
31 import org.apache.bcel.generic.InstructionList;
32 import org.apache.bcel.generic.PUSH;
33 import org.apache.xalan.xsltc.compiler.Constants;
34 import org.apache.xalan.xsltc.compiler.FlowList;
35
36 /**
37  * @author Jacek Ambroziak
38  * @author Santiago Pericas-Geertsen
39  */

40 public final class NodeSetType extends Type {
41     protected NodeSetType() {}
42
43     public String JavaDoc toString() {
44     return "node-set";
45     }
46
47     public boolean identicalTo(Type other) {
48     return this == other;
49     }
50
51     public String JavaDoc toSignature() {
52     return NODE_ITERATOR_SIG;
53     }
54
55     public org.apache.bcel.generic.Type toJCType() {
56     return new org.apache.bcel.generic.ObjectType(NODE_ITERATOR);
57     }
58
59     /**
60      * Translates a node-set into an object of internal type
61      * <code>type</code>. The translation to int is undefined
62      * since node-sets are always converted to
63      * reals in arithmetic expressions.
64      *
65      * @see org.apache.xalan.xsltc.compiler.util.Type#translateTo
66      */

67     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
68                 Type type) {
69     if (type == Type.String) {
70         translateTo(classGen, methodGen, (StringType) type);
71     }
72     else if (type == Type.Boolean) {
73         translateTo(classGen, methodGen, (BooleanType) type);
74     }
75     else if (type == Type.Real) {
76         translateTo(classGen, methodGen, (RealType) type);
77     }
78     else if (type == Type.Node) {
79         translateTo(classGen, methodGen, (NodeType) type);
80     }
81     else if (type == Type.Reference) {
82         translateTo(classGen, methodGen, (ReferenceType) type);
83     }
84     else if (type == Type.Object) {
85         translateTo(classGen, methodGen, (ObjectType) type);
86     }
87     else {
88         ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
89                     toString(), type.toString());
90         classGen.getParser().reportError(Constants.FATAL, err);
91     }
92     }
93
94     /**
95      * Translates an external Java Class into an internal type.
96      * Expects the Java object on the stack, pushes the internal type
97      */

98     public void translateFrom(ClassGenerator classGen,
99     MethodGenerator methodGen, Class JavaDoc clazz)
100     {
101         
102     InstructionList il = methodGen.getInstructionList();
103     ConstantPoolGen cpg = classGen.getConstantPool();
104     if (clazz.getName().equals("org.w3c.dom.NodeList")) {
105        // w3c NodeList is on the stack from the external Java function call.
106
// call BasisFunction to consume NodeList and leave Iterator on
107
// the stack.
108
il.append(classGen.loadTranslet()); // push translet onto stack
109
il.append(methodGen.loadDOM()); // push DOM onto stack
110
final int convert = cpg.addMethodref(BASIS_LIBRARY_CLASS,
111                     "nodeList2Iterator",
112                     "("
113                      + "Lorg/w3c/dom/NodeList;"
114                      + TRANSLET_INTF_SIG
115                      + DOM_INTF_SIG
116                      + ")" + NODE_ITERATOR_SIG );
117        il.append(new INVOKESTATIC(convert));
118     }
119     else if (clazz.getName().equals("org.w3c.dom.Node")) {
120        // w3c Node is on the stack from the external Java function call.
121
// call BasisLibrary.node2Iterator() to consume Node and leave
122
// Iterator on the stack.
123
il.append(classGen.loadTranslet()); // push translet onto stack
124
il.append(methodGen.loadDOM()); // push DOM onto stack
125
final int convert = cpg.addMethodref(BASIS_LIBRARY_CLASS,
126                     "node2Iterator",
127                     "("
128                      + "Lorg/w3c/dom/Node;"
129                      + TRANSLET_INTF_SIG
130                      + DOM_INTF_SIG
131                      + ")" + NODE_ITERATOR_SIG );
132        il.append(new INVOKESTATIC(convert));
133     }
134     else {
135         ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
136         toString(), clazz.getName());
137         classGen.getParser().reportError(Constants.FATAL, err);
138     }
139     }
140
141
142     /**
143      * Translates a node-set into a synthesized boolean.
144      * The boolean value of a node-set is "true" if non-empty
145      * and "false" otherwise. Notice that the
146      * function getFirstNode() is called in translateToDesynthesized().
147      *
148      * @see org.apache.xalan.xsltc.compiler.util.Type#translateTo
149      */

150     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
151                 BooleanType type) {
152     final InstructionList il = methodGen.getInstructionList();
153     FlowList falsel = translateToDesynthesized(classGen, methodGen, type);
154     il.append(ICONST_1);
155     final BranchHandle truec = il.append(new GOTO(null));
156     falsel.backPatch(il.append(ICONST_0));
157     truec.setTarget(il.append(NOP));
158     }
159
160     /**
161      * Translates a node-set into a string. The string value of a node-set is
162      * value of its first element.
163      *
164      * @see org.apache.xalan.xsltc.compiler.util.Type#translateTo
165      */

166     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
167                 StringType type) {
168     final InstructionList il = methodGen.getInstructionList();
169     getFirstNode(classGen, methodGen);
170     il.append(DUP);
171     final BranchHandle falsec = il.append(new IFLT(null));
172     Type.Node.translateTo(classGen, methodGen, type);
173     final BranchHandle truec = il.append(new GOTO(null));
174     falsec.setTarget(il.append(POP));
175     il.append(new PUSH(classGen.getConstantPool(), ""));
176     truec.setTarget(il.append(NOP));
177     }
178
179     /**
180      * Expects a node-set on the stack and pushes a real.
181      * First the node-set is converted to string, and from string to real.
182      *
183      * @see org.apache.xalan.xsltc.compiler.util.Type#translateTo
184      */

185     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
186                 RealType type) {
187     translateTo(classGen, methodGen, Type.String);
188     Type.String.translateTo(classGen, methodGen, Type.Real);
189     }
190
191     /**
192      * Expects a node-set on the stack and pushes a node.
193      *
194      * @see org.apache.xalan.xsltc.compiler.util.Type#translateTo
195      */

196     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
197                 NodeType type) {
198     getFirstNode(classGen, methodGen);
199     }
200
201     /**
202      * Subsume node-set into ObjectType.
203      *
204      * @see org.apache.xalan.xsltc.compiler.util.Type#translateTo
205      */

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

218     public FlowList translateToDesynthesized(ClassGenerator classGen,
219                          MethodGenerator methodGen,
220                          BooleanType type) {
221     final InstructionList il = methodGen.getInstructionList();
222     getFirstNode(classGen, methodGen);
223     return new FlowList(il.append(new IFLT(null)));
224     }
225
226     /**
227      * Expects a node-set on the stack and pushes a boxed node-set.
228      * Node sets are already boxed so the translation is just a NOP.
229      *
230      * @see org.apache.xalan.xsltc.compiler.util.Type#translateTo
231      */

232     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
233                 ReferenceType type) {
234     methodGen.getInstructionList().append(NOP);
235     }
236
237     /**
238      * Translates a node-set into the Java type denoted by <code>clazz</code>.
239      * Expects a node-set on the stack and pushes an object of the appropriate
240      * type after coercion.
241      */

242     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
243                 Class JavaDoc clazz) {
244     final ConstantPoolGen cpg = classGen.getConstantPool();
245     final InstructionList il = methodGen.getInstructionList();
246     final String JavaDoc className = clazz.getName();
247
248     il.append(methodGen.loadDOM());
249     il.append(SWAP);
250
251     if (className.equals("org.w3c.dom.Node")) {
252         int index = cpg.addInterfaceMethodref(DOM_INTF,
253                           MAKE_NODE,
254                           MAKE_NODE_SIG2);
255         il.append(new INVOKEINTERFACE(index, 2));
256     }
257         else if (className.equals("org.w3c.dom.NodeList") ||
258                  className.equals("java.lang.Object")) {
259         int index = cpg.addInterfaceMethodref(DOM_INTF,
260                           MAKE_NODE_LIST,
261                           MAKE_NODE_LIST_SIG2);
262         il.append(new INVOKEINTERFACE(index, 2));
263     }
264         else if (className.equals("java.lang.String")) {
265             int next = cpg.addInterfaceMethodref(NODE_ITERATOR,
266                                                  "next", "()I");
267             int index = cpg.addInterfaceMethodref(DOM_INTF,
268                                                  GET_NODE_VALUE,
269                                                  "(I)"+STRING_SIG);
270
271             // Get next node from the iterator
272
il.append(new INVOKEINTERFACE(next, 1));
273             // Get the node's string value (from the DOM)
274
il.append(new INVOKEINTERFACE(index, 2));
275                        
276         }
277     else {
278         ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
279                     toString(), className);
280         classGen.getParser().reportError(Constants.FATAL, err);
281     }
282     }
283     
284     /**
285      * Some type conversions require gettting the first node from the node-set.
286      * This function is defined to avoid code repetition.
287      */

288     private void getFirstNode(ClassGenerator classGen, MethodGenerator methodGen) {
289     final ConstantPoolGen cpg = classGen.getConstantPool();
290     final InstructionList il = methodGen.getInstructionList();
291     il.append(new INVOKEINTERFACE(cpg.addInterfaceMethodref(NODE_ITERATOR,
292                                 NEXT,
293                                 NEXT_SIG), 1));
294     }
295
296     /**
297      * Translates an object of this type to its boxed representation.
298      */

299     public void translateBox(ClassGenerator classGen,
300                  MethodGenerator methodGen) {
301     translateTo(classGen, methodGen, Type.Reference);
302     }
303
304     /**
305      * Translates an object of this type to its unboxed representation.
306      */

307     public void translateUnBox(ClassGenerator classGen,
308                    MethodGenerator methodGen) {
309     methodGen.getInstructionList().append(NOP);
310     }
311
312     /**
313      * Returns the class name of an internal type's external representation.
314      */

315     public String JavaDoc getClassName() {
316     return(NODE_ITERATOR);
317     }
318
319
320     public Instruction LOAD(int slot) {
321     return new ALOAD(slot);
322     }
323     
324     public Instruction STORE(int slot) {
325     return new ASTORE(slot);
326     }
327 }
328
Popular Tags