1 16 package net.sf.cglib.beans; 17 18 import java.lang.reflect.Constructor ; 19 import java.lang.reflect.Method ; 20 import java.lang.reflect.Modifier ; 21 import java.util.*; 22 import net.sf.cglib.core.*; 23 import org.objectweb.asm.ClassVisitor; 24 import org.objectweb.asm.Type; 25 26 class BulkBeanEmitter extends ClassEmitter { 27 private static final Signature GET_PROPERTY_VALUES = 28 TypeUtils.parseSignature("void getPropertyValues(Object, Object[])"); 29 private static final Signature SET_PROPERTY_VALUES = 30 TypeUtils.parseSignature("void setPropertyValues(Object, Object[])"); 31 private static final Signature CSTRUCT_EXCEPTION = 32 TypeUtils.parseConstructor("Throwable, int"); 33 private static final Type BULK_BEAN = 34 TypeUtils.parseType("net.sf.cglib.beans.BulkBean"); 35 private static final Type BULK_BEAN_EXCEPTION = 36 TypeUtils.parseType("net.sf.cglib.beans.BulkBeanException"); 37 38 public BulkBeanEmitter(ClassVisitor v, 39 String className, 40 Class target, 41 String [] getterNames, 42 String [] setterNames, 43 Class [] types) { 44 super(v); 45 46 Method [] getters = new Method [getterNames.length]; 47 Method [] setters = new Method [setterNames.length]; 48 validate(target, getterNames, setterNames, types, getters, setters); 49 50 begin_class(Constants.V1_2, Constants.ACC_PUBLIC, className, BULK_BEAN, null, Constants.SOURCE_FILE); 51 EmitUtils.null_constructor(this); 52 generateGet(target, getters); 53 generateSet(target, setters); 54 end_class(); 55 } 56 57 private void generateGet(final Class target, final Method [] getters) { 58 CodeEmitter e = begin_method(Constants.ACC_PUBLIC, GET_PROPERTY_VALUES, null); 59 if (getters.length >= 0) { 60 e.load_arg(0); 61 e.checkcast(Type.getType(target)); 62 Local bean = e.make_local(); 63 e.store_local(bean); 64 for (int i = 0; i < getters.length; i++) { 65 if (getters[i] != null) { 66 MethodInfo getter = ReflectUtils.getMethodInfo(getters[i]); 67 e.load_arg(1); 68 e.push(i); 69 e.load_local(bean); 70 e.invoke(getter); 71 e.box(getter.getSignature().getReturnType()); 72 e.aastore(); 73 } 74 } 75 } 76 e.return_value(); 77 e.end_method(); 78 } 79 80 private void generateSet(final Class target, final Method [] setters) { 81 CodeEmitter e = begin_method(Constants.ACC_PUBLIC, SET_PROPERTY_VALUES, null); 83 if (setters.length > 0) { 84 Local index = e.make_local(Type.INT_TYPE); 85 e.push(0); 86 e.store_local(index); 87 e.load_arg(0); 88 e.checkcast(Type.getType(target)); 89 e.load_arg(1); 90 Block handler = e.begin_block(); 91 int lastIndex = 0; 92 for (int i = 0; i < setters.length; i++) { 93 if (setters[i] != null) { 94 MethodInfo setter = ReflectUtils.getMethodInfo(setters[i]); 95 int diff = i - lastIndex; 96 if (diff > 0) { 97 e.iinc(index, diff); 98 lastIndex = i; 99 } 100 e.dup2(); 101 e.aaload(i); 102 e.unbox(setter.getSignature().getArgumentTypes()[0]); 103 e.invoke(setter); 104 } 105 } 106 handler.end(); 107 e.return_value(); 108 e.catch_exception(handler, Constants.TYPE_THROWABLE); 109 e.new_instance(BULK_BEAN_EXCEPTION); 110 e.dup_x1(); 111 e.swap(); 112 e.load_local(index); 113 e.invoke_constructor(BULK_BEAN_EXCEPTION, CSTRUCT_EXCEPTION); 114 e.athrow(); 115 } else { 116 e.return_value(); 117 } 118 e.end_method(); 119 } 120 121 private static void validate(Class target, 122 String [] getters, 123 String [] setters, 124 Class [] types, 125 Method [] getters_out, 126 Method [] setters_out) { 127 int i = -1; 128 if (setters.length != types.length || getters.length != types.length) { 129 throw new BulkBeanException("accessor array length must be equal type array length", i); 130 } 131 try { 132 for (i = 0; i < types.length; i++) { 133 if (getters[i] != null) { 134 Method method = ReflectUtils.findDeclaredMethod(target, getters[i], null); 135 if (method.getReturnType() != types[i]) { 136 throw new BulkBeanException("Specified type " + types[i] + 137 " does not match declared type " + method.getReturnType(), i); 138 } 139 if (Modifier.isPrivate(method.getModifiers())) { 140 throw new BulkBeanException("Property is private", i); 141 } 142 getters_out[i] = method; 143 } 144 if (setters[i] != null) { 145 Method method = ReflectUtils.findDeclaredMethod(target, setters[i], new Class []{ types[i] }); 146 if (Modifier.isPrivate(method.getModifiers()) ){ 147 throw new BulkBeanException("Property is private", i); 148 } 149 setters_out[i] = method; 150 } 151 } 152 } catch (NoSuchMethodException e) { 153 throw new BulkBeanException("Cannot find specified property", i); 154 } 155 } 156 } 157 | Popular Tags |