KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > versant > core > jdo > query > mem > ByteCodeQCompareVisitor


1
2 /*
3  * Copyright (c) 1998 - 2005 Versant Corporation
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  * Versant Corporation - initial API and implementation
11  */

12 package com.versant.core.jdo.query.mem;
13
14 import com.versant.core.jdo.query.*;
15 import com.versant.core.jdo.query.MemVisitor;
16 import com.versant.core.metadata.FieldMetaData;
17 import com.versant.core.metadata.ClassMetaData;
18 import com.versant.core.metadata.MDStatics;
19
20 import com.versant.lib.bcel.generic.*;
21 import com.versant.lib.bcel.Constants;
22
23 import com.versant.core.common.BindingSupportImpl;
24 import com.versant.core.jdo.QueryStateWrapper;
25
26 /**
27  * Compiles ordering expression to bytecode.
28  */

29 public class ByteCodeQCompareVisitor implements MemVisitor {
30
31     private ClassMetaData candidateClass;
32     private ClassGen cg;
33     private ConstantPoolGen cp;
34     private InstructionList il;
35     private MethodGen mg;
36     private InstructionFactory factory;
37
38     private boolean first = true;
39
40     private static final String JavaDoc NAME_Q_STATE_WRAPPER = QueryStateWrapper.class.getName();
41     private static final String JavaDoc M_NAME_GETSTATE = "getState";
42
43
44     private static final String JavaDoc NAME_COMPARABLE = Comparable JavaDoc.class.getName();
45
46     private static final Type[] ARG_TYPES_INT = new Type[] {Type.INT};
47     private static final Type[] ARG_TYPES_OBJECT = new Type[] {Type.OBJECT};
48
49
50     private int stateParamNo = 1;
51     private boolean ascending = false;
52     private int var1Index;
53
54
55     public ByteCodeQCompareVisitor(ClassGen classGen, InstructionFactory factory, String JavaDoc name, ClassMetaData candidateClass) {
56         this.candidateClass = candidateClass;
57         cg = classGen;
58         this.factory = factory;
59         cp = cg.getConstantPool();
60
61         this.il = new InstructionList();
62         mg = new MethodGen(Constants.ACC_PUBLIC, // access flags
63
Type.INT, // return type
64
new Type[] {new ObjectType(NAME_Q_STATE_WRAPPER), new ObjectType(NAME_Q_STATE_WRAPPER)},
65                                         new String JavaDoc[] {"state1", "state2"}, // arg names
66
"compare", name, // method, class
67
this.il, cp);
68
69
70         //create localVar for declared var
71
il.append(InstructionConstants.ICONST_0);
72         LocalVariableGen var1 = mg.addLocalVariable("compResult",
73                 Type.INT, null, null);
74         var1Index = var1.getIndex();
75         il.append(new ISTORE(var1Index));
76         var1.setStart(il.append(new NOP()));
77     }
78
79     public void finish() {
80         il.append(new ILOAD(var1Index));
81         il.append(InstructionConstants.IRETURN);
82         mg.removeNOPs();
83         mg.setMaxLocals();
84         mg.setMaxStack();
85         cg.addMethod(mg.getMethod());
86         il.dispose();
87     }
88
89     public Field visitNode(Node node, Object JavaDoc obj) {
90         throw BindingSupportImpl.getInstance().notImplemented(null);
91     }
92
93     /**
94      * Must refactor
95      * @param node
96      * @param obj
97      * @return
98      */

99     public Field visitLiteralNode(LiteralNode node, Object JavaDoc obj) {
100         throw BindingSupportImpl.getInstance().notImplemented(null);
101     }
102
103     /**
104      * This may be an state field on a state eg person.person
105      * @param node
106      * @param obj
107      * @return
108      */

109     public Field visitFieldNavNode(FieldNavNode node, Object JavaDoc obj) {
110         return visitStateFieldNavNodeRoot(node, candidateClass);
111     }
112
113     private Field visitStateFieldNavNodeRoot(FieldNavNode node, ClassMetaData currentClass) {
114         FieldMetaData f = null;
115         f = currentClass.getFieldMetaData(node.lexeme);
116         if(f == null){
117             throw BindingSupportImpl.getInstance().runtime("Class "+currentClass+
118                     " does not have a field "+ node.lexeme);
119         }
120         switch(f.category){
121             case FieldMetaData.CATEGORY_REF:
122                 InstructionHandle ih = null;
123                 il.append(new ALOAD(stateParamNo));//load the state
124
il.append(new PUSH(cp, f.stateFieldNo));
125                 il.append(factory.createInvoke(NAME_Q_STATE_WRAPPER, M_NAME_GETSTATE,
126                         new ObjectType(NAME_Q_STATE_WRAPPER), ARG_TYPES_INT, Constants.INVOKEVIRTUAL));
127                 first = false;
128                 if (node.childList instanceof FieldNavNode) {
129                     visitStateFieldNavNode((FieldNavNode) node.childList, f.typeMetaData, ih);
130                 } else {
131                     visitFieldNode((FieldNode) node.childList, f.typeMetaData);
132                 }
133                 break;
134             default:
135                 throw BindingSupportImpl.getInstance().internal("Only PersistenceCapable fields can be navigated");
136         }
137         return null;
138     }
139
140     private Field visitStateFieldNavNode(FieldNavNode node, ClassMetaData currentClass, InstructionHandle ih) {
141         Field result = null;
142         FieldMetaData f = currentClass.getFieldMetaData(node.lexeme);
143         if(f == null){
144             throw BindingSupportImpl.getInstance().runtime("Class "+currentClass+
145                     " does not have a field "+ node.lexeme);
146         }
147         switch(f.category){
148             case FieldMetaData.CATEGORY_REF:
149                 il.append(new PUSH(cp, f.stateFieldNo));
150                 il.append(factory.createInvoke(NAME_Q_STATE_WRAPPER, M_NAME_GETSTATE,
151                         new ObjectType(NAME_Q_STATE_WRAPPER), ARG_TYPES_INT, Constants.INVOKEVIRTUAL));
152                 if (node.childList instanceof FieldNavNode) {
153                     result = visitStateFieldNavNode((FieldNavNode) node.childList, f.typeMetaData, ih);
154                 } else {
155                     result = visitFieldNode((FieldNode) node.childList, f.typeMetaData);
156                 }
157                 break;
158             default:
159                 throw BindingSupportImpl.getInstance().internal("Only PersistenceCapable fields can be navigated");
160         }
161         return result;
162     }
163
164     public Field visitMethodNode(MethodNode node, Object JavaDoc obj) {
165         throw BindingSupportImpl.getInstance().notImplemented(null);
166     }
167
168     public Field visitPrimaryExprNode(PrimaryExprNode node, Object JavaDoc obj) {
169         return null;
170     }
171
172     public Field visitFieldNode(FieldNode node, ClassMetaData cmd) {
173         if (cmd == null) {
174             return visitFieldNodeImp(candidateClass.getFieldMetaData(node.lexeme), node);
175         } else {
176             return visitFieldNodeImp(cmd.getFieldMetaData(node.lexeme), node);
177         }
178     }
179
180     private Field visitFieldNodeImp(FieldMetaData fmd, FieldNode node) {
181         if (fmd == null) {
182             throw BindingSupportImpl.getInstance().runtime("Class " + candidateClass.qname + " does not have a field: " + node.lexeme);
183         }
184         if (first) {
185             first = false;
186             il.append(new ALOAD(stateParamNo));//load state on stack
187
il.append(new PUSH(cp, fmd.stateFieldNo));
188         } else {
189             il.append(new PUSH(cp, fmd.stateFieldNo));
190         }
191         il.append(factory.createInvoke(NAME_Q_STATE_WRAPPER, fmd.stateGetMethodName, getBCellStateFieldType(fmd),
192                 ARG_TYPES_INT, Constants.INVOKEVIRTUAL));
193
194         if (stateParamNo == 2) {
195             if (fmd.type.isPrimitive()) {
196                 switch (fmd.typeCode) {
197                     case MDStatics.BYTE:
198                     case MDStatics.SHORT:
199                     case MDStatics.CHAR:
200                     case MDStatics.INT:
201                         il.append(InstructionConstants.ISUB);
202                         break;
203                     case MDStatics.LONG:
204                         il.append(InstructionConstants.LSUB);
205                         il.append(InstructionConstants.L2I);
206                         break;
207                     case MDStatics.FLOAT:
208                         il.append(factory.createInvoke(Float JavaDoc.class.getName(), "compare", Type.INT,
209                             new Type[] {Type.FLOAT, Type.FLOAT}, Constants.INVOKEVIRTUAL));
210                         break;
211                     case MDStatics.DOUBLE:
212                         il.append(factory.createInvoke(Double JavaDoc.class.getName(), "compare", Type.INT,
213                             new Type[] {Type.DOUBLE, Type.DOUBLE}, Constants.INVOKEVIRTUAL));
214
215                         break;
216                     default:
217                         throw BindingSupportImpl.getInstance().notImplemented(null);
218                 }
219
220             } else {
221                 il.append(factory.createInvoke(NAME_COMPARABLE, "compareTo", Type.INT,
222                     ARG_TYPES_OBJECT, Constants.INVOKEINTERFACE));
223             }
224
225             if (ascending) {
226                 il.append(InstructionConstants.ICONST_M1);
227                 il.append(InstructionConstants.IMUL);
228             }
229             il.append(new ISTORE(var1Index));
230
231             il.append(new ILOAD(var1Index));
232             BranchInstruction bInstr = new IFEQ(null);
233             il.append(bInstr);
234
235             il.append(new ILOAD(var1Index));
236             il.append(InstructionConstants.IRETURN);
237
238             InstructionHandle endHandle = il.append(InstructionConstants.NOP);
239             bInstr.setTarget(endHandle);
240
241         }
242         return null;
243     }
244
245     public Field visitFieldNode(FieldNode node, Object JavaDoc obj) {
246         return visitFieldNodeImp(candidateClass.getFieldMetaData(node.lexeme), node);
247     }
248
249     private static final Type getBCellStateFieldType(FieldMetaData fmd) {
250         switch (fmd.category) {
251             case MDStatics.CATEGORY_SIMPLE:
252                 return getTypeFromTypeCode(fmd.typeCode);
253             default:
254                 return Type.OBJECT;
255         }
256     }
257
258     private static Type getTypeFromTypeCode(int typeCode) {
259         switch (typeCode) {
260             case MDStatics.INT:
261                 return Type.INT;
262             case MDStatics.LONG:
263                 return Type.LONG;
264             case MDStatics.SHORT:
265                 return Type.SHORT;
266             case MDStatics.STRING:
267                 return Type.STRING;
268             case MDStatics.BOOLEAN:
269                 return Type.BOOLEAN;
270             case MDStatics.BYTE:
271                 return Type.BYTE;
272             case MDStatics.CHAR:
273                 return Type.CHAR;
274             case MDStatics.DOUBLE:
275                 return Type.DOUBLE;
276             case MDStatics.FLOAT:
277                 return Type.FLOAT;
278             default:
279                 return Type.OBJECT;
280         }
281     }
282
283     public Field visitEqualNode(EqualNode node, Object JavaDoc obj) {
284         throw BindingSupportImpl.getInstance().notImplemented(null);
285     }
286
287     public Field visitNotEqualNode(NotEqualNode node, Object JavaDoc obj) {
288         throw BindingSupportImpl.getInstance().notImplemented(null);
289     }
290
291     public Field visitLikeNode(LikeNode node, Object JavaDoc obj) {
292         return null;
293     }
294
295     public Field visitAndNode(AndNode node, Object JavaDoc obj) {
296         throw BindingSupportImpl.getInstance().notImplemented(null);
297     }
298
299     public Field visitOrNode(OrNode node, Object JavaDoc obj) {
300         throw BindingSupportImpl.getInstance().notImplemented(null);
301     }
302
303     public Field visitMultiplyNode(MultiplyNode node, Object JavaDoc obj) {
304         throw BindingSupportImpl.getInstance().notImplemented(null);
305     }
306
307     public Field visitAddNode(AddNode node, Object JavaDoc obj) {
308         throw BindingSupportImpl.getInstance().notImplemented(null);
309     }
310
311     public Field visitUnaryOpNode(UnaryOpNode node, Object JavaDoc obj) {
312         throw BindingSupportImpl.getInstance().notImplemented(null);
313     }
314
315     public Field visitCompareOpNode(CompareOpNode node, Object JavaDoc obj) {
316         throw BindingSupportImpl.getInstance().notImplemented(null);
317     }
318
319     public Field visitUnaryNode(UnaryNode node, Object JavaDoc obj) {
320         node.childList.visit(this,obj);
321         return null;
322     }
323
324     public Field visitBinaryNode(BinaryNode node, Object JavaDoc obj) {
325         return null;
326     }
327
328     public Field visitMultiNode(Node node, Object JavaDoc obj) {
329         return null;
330     }
331
332     public Field visitCastNode(CastNode node, Object JavaDoc obj) {
333         return null;
334     }
335
336     public Field visitParamNode(ParamNode node, Object JavaDoc obj) {
337         throw BindingSupportImpl.getInstance().notImplemented(null);
338     }
339
340     public Field visitParamNodeProxy(ParamNodeProxy node, Object JavaDoc obj) {
341         return node.getParamNode().visit(this, obj);
342     }
343
344     public Field visitArgNode(ArgNode node, Object JavaDoc obj) {
345         return null;
346     }
347
348     public Field visitArrayNode(ArrayNode node, Object JavaDoc obj) {
349         return null;
350     }
351
352     public Field visitImportNode(ImportNode node, Object JavaDoc obj) {
353         return null;
354     }
355
356     public Field visitLeafNode(LeafNode node, Object JavaDoc obj) {
357         return null;
358     }
359
360     public Field visitOrderNode(OrderNode node, Object JavaDoc obj) {
361         if (node.order == OrderNode.ORDER_ASCENDING) {
362             ascending = true;
363         } else {
364             ascending = false;
365         }
366         first = true;
367         stateParamNo = 1;
368         node.childList.visit(this, obj);
369         first = true;
370         stateParamNo = 2;
371         node.childList.visit(this, obj);
372         return null;
373     }
374
375     public Field visitVarNode(VarNode node, Object JavaDoc obj) {
376         return null;
377     }
378
379     public Field visitVarNodeProxy(VarNodeProxy node, Object JavaDoc obj) {
380         return node.getVarNode().visit(this, obj);
381     }
382
383     public Field visitReservedFieldNode(ReservedFieldNode node, Object JavaDoc obj) {
384         return null;
385     }
386 }
387
Popular Tags