1 | /* |
2 | * Copyright 2007 brunella ltd |
3 | * |
4 | * Licensed under the LGPL Version 3 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * |
7 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
8 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
9 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
10 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
11 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
12 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
13 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
14 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
15 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
16 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
17 | * THE POSSIBILITY OF SUCH DAMAGE. |
18 | */ |
19 | package sf.qof.codegen; |
20 | |
21 | import static sf.qof.codegen.Constants.SIG_Boolean_valueOf; |
22 | import static sf.qof.codegen.Constants.SIG_Byte_valueOf; |
23 | import static sf.qof.codegen.Constants.SIG_Character_valueOf; |
24 | import static sf.qof.codegen.Constants.SIG_Double_valueOf; |
25 | import static sf.qof.codegen.Constants.SIG_Float_valueOf; |
26 | import static sf.qof.codegen.Constants.SIG_Integer_valueOf; |
27 | import static sf.qof.codegen.Constants.SIG_Long_valueOf; |
28 | import static sf.qof.codegen.Constants.SIG_Short_valueOf; |
29 | import static sf.qof.codegen.Constants.SIG_close; |
30 | import static sf.qof.codegen.Constants.TYPE_Boolean; |
31 | import static sf.qof.codegen.Constants.TYPE_Byte; |
32 | import static sf.qof.codegen.Constants.TYPE_Character; |
33 | import static sf.qof.codegen.Constants.TYPE_Double; |
34 | import static sf.qof.codegen.Constants.TYPE_Float; |
35 | import static sf.qof.codegen.Constants.TYPE_Integer; |
36 | import static sf.qof.codegen.Constants.TYPE_Long; |
37 | import static sf.qof.codegen.Constants.TYPE_Short; |
38 | import static sf.qof.codegen.Constants.TYPE_boolean; |
39 | import static sf.qof.codegen.Constants.TYPE_byte; |
40 | import static sf.qof.codegen.Constants.TYPE_char; |
41 | import static sf.qof.codegen.Constants.TYPE_double; |
42 | import static sf.qof.codegen.Constants.TYPE_float; |
43 | import static sf.qof.codegen.Constants.TYPE_int; |
44 | import static sf.qof.codegen.Constants.TYPE_long; |
45 | import static sf.qof.codegen.Constants.TYPE_short; |
46 | |
47 | import java.lang.reflect.Constructor; |
48 | |
49 | import net.sf.cglib.core.CodeEmitter; |
50 | import net.sf.cglib.core.Local; |
51 | import net.sf.cglib.core.Signature; |
52 | |
53 | import org.objectweb.asm.Label; |
54 | import org.objectweb.asm.Type; |
55 | |
56 | import sf.qof.mapping.Mapper; |
57 | |
58 | /** |
59 | * Internal - Contains utility functions for code emitters. |
60 | */ |
61 | public class EmitUtils { |
62 | |
63 | private EmitUtils() { |
64 | } |
65 | |
66 | /** |
67 | * Emits code to call the static <code>valueOf</code> method of the |
68 | * boxed types of primitives. |
69 | * |
70 | * @param co the code emitter |
71 | * @param primitiveType primitive type |
72 | */ |
73 | public static void boxUsingValueOf(CodeEmitter co, Type primitiveType) { |
74 | if (primitiveType == TYPE_byte) { |
75 | co.invoke_static(TYPE_Byte, SIG_Byte_valueOf); |
76 | } else if (primitiveType == TYPE_short) { |
77 | co.invoke_static(TYPE_Short, SIG_Short_valueOf); |
78 | } else if (primitiveType == TYPE_int) { |
79 | co.invoke_static(TYPE_Integer, SIG_Integer_valueOf); |
80 | } else if (primitiveType == TYPE_long) { |
81 | co.invoke_static(TYPE_Long, SIG_Long_valueOf); |
82 | } else if (primitiveType == TYPE_float) { |
83 | co.invoke_static(TYPE_Float, SIG_Float_valueOf); |
84 | } else if (primitiveType == TYPE_double) { |
85 | co.invoke_static(TYPE_Double, SIG_Double_valueOf); |
86 | } else if (primitiveType == TYPE_char) { |
87 | co.invoke_static(TYPE_Character, SIG_Character_valueOf); |
88 | } else if (primitiveType == TYPE_boolean) { |
89 | co.invoke_static(TYPE_Boolean, SIG_Boolean_valueOf); |
90 | } |
91 | } |
92 | |
93 | /** |
94 | * Emits code to call <code>close()</code> on the local variable. |
95 | * |
96 | * @param co the code emitter |
97 | * @param local the local |
98 | * @param addIfNotNull add if not null check |
99 | */ |
100 | public static void emitClose(CodeEmitter co, Local local, boolean addIfNotNull) { |
101 | Label labelNull = null; |
102 | if (addIfNotNull) { |
103 | co.load_local(local); |
104 | labelNull = co.make_label(); |
105 | co.ifnull(labelNull); |
106 | } |
107 | co.load_local(local); |
108 | co.invoke_interface(local.getType(), SIG_close); |
109 | if (addIfNotNull) { |
110 | co.mark(labelNull); |
111 | } |
112 | } |
113 | |
114 | public static void createAndStoreNewResultObject(CodeEmitter co, Mapper mapper, Local localResultSet, Local localStoreResult) { |
115 | // constructor mappings |
116 | Local[] constructorParameters = new Local[mapper.getNumberOfConstructorParameters()]; |
117 | ResultMappingGenerator rmp = new ResultMappingGenerator(co, localResultSet, null, null, true, constructorParameters); |
118 | mapper.acceptResultMappers(rmp); |
119 | |
120 | co.new_instance(localStoreResult.getType()); |
121 | co.dup(); |
122 | |
123 | for (int i = 0; i < constructorParameters.length; i++) { |
124 | co.load_local(constructorParameters[i]); |
125 | } |
126 | if (mapper.getConstructor() == null) { |
127 | co.invoke_constructor(localStoreResult.getType()); |
128 | } else { |
129 | Signature constructorSignature = createConstructorSignature(mapper.getConstructor()); |
130 | co.invoke_constructor(localStoreResult.getType(), constructorSignature); |
131 | } |
132 | co.store_local(localStoreResult); |
133 | } |
134 | |
135 | private static Signature createConstructorSignature(Constructor<?> constructor) { |
136 | Class<?>[] constructorParameterTypes = constructor.getParameterTypes(); |
137 | Type[] parameterTypes = new Type[constructorParameterTypes.length]; |
138 | for (int i = 0; i < constructorParameterTypes.length; i++) { |
139 | parameterTypes[i] = Type.getType(constructorParameterTypes[i]); |
140 | } |
141 | return new Signature("<init>", Type.getType(void.class), parameterTypes); |
142 | } |
143 | |
144 | } |