| 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 | } |