@SuppressWarnings({"rawtypes"}) class DispatcherGenerator implements CallbackGenerator { public static final DispatcherGenerator INSTANCE = new DispatcherGenerator(false); public static final DispatcherGenerator PROXY_REF_INSTANCE = new DispatcherGenerator(true); private static final Type DISPATCHER = TypeUtils.parseType("ext.jtester.cglib.proxy.Dispatcher"); private static final Type PROXY_REF_DISPATCHER = TypeUtils.parseType("ext.jtester.cglib.proxy.ProxyRefDispatcher"); private static final Signature LOAD_OBJECT = TypeUtils.parseSignature("Object loadObject()"); private static final Signature PROXY_REF_LOAD_OBJECT = TypeUtils.parseSignature("Object loadObject(Object)"); private boolean proxyRef; private DispatcherGenerator(boolean proxyRef) { this.proxyRef = proxyRef; } public void generate(ClassEmitter ce, Context context, List methods) { for (Iterator it = methods.iterator(); it.hasNext(); ) { MethodInfo method = (MethodInfo) it.next(); if (!TypeUtils.isProtected(method.getModifiers())) { CodeEmitter e = context.beginMethod(ce, method); context.emitCallback(e, context.getIndex(method)); if (proxyRef) { e.load_this(); e.invoke_interface(PROXY_REF_DISPATCHER, PROXY_REF_LOAD_OBJECT); } else { e.invoke_interface(DISPATCHER, LOAD_OBJECT); } e.checkcast(method.getClassInfo().getType()); e.load_args(); e.invoke(method); e.return_value(); e.end_method(); } } } public void generateStatic(CodeEmitter e, Context context, List methods) {} }
class InvocationHandlerGenerator implements CallbackGenerator { public static final InvocationHandlerGenerator INSTANCE = new InvocationHandlerGenerator(); private static final Type INVOCATION_HANDLER = TypeUtils.parseType("net.sf.cglib.proxy.InvocationHandler"); private static final Type UNDECLARED_THROWABLE_EXCEPTION = TypeUtils.parseType("net.sf.cglib.proxy.UndeclaredThrowableException"); private static final Type METHOD = TypeUtils.parseType("java.lang.reflect.Method"); private static final Signature INVOKE = TypeUtils.parseSignature("Object invoke(Object, java.lang.reflect.Method, Object[])"); public void generate(ClassEmitter ce, Context context, List methods) { for (Iterator it = methods.iterator(); it.hasNext(); ) { MethodInfo method = (MethodInfo) it.next(); Signature impl = context.getImplSignature(method); ce.declare_field(Constants.PRIVATE_FINAL_STATIC, impl.getName(), METHOD, null); CodeEmitter e = context.beginMethod(ce, method); Block handler = e.begin_block(); context.emitCallback(e, context.getIndex(method)); e.load_this(); e.getfield(impl.getName()); e.create_arg_array(); e.invoke_interface(INVOCATION_HANDLER, INVOKE); e.unbox(method.getSignature().getReturnType()); e.return_value(); handler.end(); EmitUtils.wrap_undeclared_throwable( e, handler, method.getExceptionTypes(), UNDECLARED_THROWABLE_EXCEPTION); e.end_method(); } } public void generateStatic(CodeEmitter e, Context context, List methods) { for (Iterator it = methods.iterator(); it.hasNext(); ) { MethodInfo method = (MethodInfo) it.next(); EmitUtils.load_method(e, method); e.putfield(context.getImplSignature(method).getName()); } } }
class BulkBeanEmitter extends ClassEmitter { private static final Signature GET_PROPERTY_VALUES = TypeUtils.parseSignature("void getPropertyValues(Object, Object[])"); private static final Signature SET_PROPERTY_VALUES = TypeUtils.parseSignature("void setPropertyValues(Object, Object[])"); private static final Signature CSTRUCT_EXCEPTION = TypeUtils.parseConstructor("Throwable, int"); private static final Type BULK_BEAN = TypeUtils.parseType("net.sf.cglib.beans.BulkBean"); private static final Type BULK_BEAN_EXCEPTION = TypeUtils.parseType("net.sf.cglib.beans.BulkBeanException"); public BulkBeanEmitter(ClassVisitor v, String className, Class target, String[] getterNames, String[] setterNames, Class[] types) { super(v); Method[] getters = new Method[getterNames.length]; Method[] setters = new Method[setterNames.length]; validate(target, getterNames, setterNames, types, getters, setters); begin_class(Constants.V1_2, Constants.ACC_PUBLIC, className, BULK_BEAN, null, Constants.SOURCE_FILE); EmitUtils.null_constructor(this); generateGet(target, getters); generateSet(target, setters); end_class(); } private void generateGet(final Class target, final Method[] getters) { CodeEmitter e = begin_method(Constants.ACC_PUBLIC, GET_PROPERTY_VALUES, null); if (getters.length >= 0) { e.load_arg(0); e.checkcast(Type.getType(target)); Local bean = e.make_local(); e.store_local(bean); for (int i = 0; i < getters.length; i++) { if (getters[i] != null) { MethodInfo getter = ReflectUtils.getMethodInfo(getters[i]); e.load_arg(1); e.push(i); e.load_local(bean); e.invoke(getter); e.box(getter.getSignature().getReturnType()); e.aastore(); } } } e.return_value(); e.end_method(); } private void generateSet(final Class target, final Method[] setters) { // setPropertyValues CodeEmitter e = begin_method(Constants.ACC_PUBLIC, SET_PROPERTY_VALUES, null); if (setters.length > 0) { Local index = e.make_local(Type.INT_TYPE); e.push(0); e.store_local(index); e.load_arg(0); e.checkcast(Type.getType(target)); e.load_arg(1); Block handler = e.begin_block(); int lastIndex = 0; for (int i = 0; i < setters.length; i++) { if (setters[i] != null) { MethodInfo setter = ReflectUtils.getMethodInfo(setters[i]); int diff = i - lastIndex; if (diff > 0) { e.iinc(index, diff); lastIndex = i; } e.dup2(); e.aaload(i); e.unbox(setter.getSignature().getArgumentTypes()[0]); e.invoke(setter); } } handler.end(); e.return_value(); e.catch_exception(handler, Constants.TYPE_THROWABLE); e.new_instance(BULK_BEAN_EXCEPTION); e.dup_x1(); e.swap(); e.load_local(index); e.invoke_constructor(BULK_BEAN_EXCEPTION, CSTRUCT_EXCEPTION); e.athrow(); } else { e.return_value(); } e.end_method(); } private static void validate(Class target, String[] getters, String[] setters, Class[] types, Method[] getters_out, Method[] setters_out) { int i = -1; if (setters.length != types.length || getters.length != types.length) { throw new BulkBeanException("accessor array length must be equal type array length", i); } try { for (i = 0; i < types.length; i++) { if (getters[i] != null) { Method method = ReflectUtils.findDeclaredMethod(target, getters[i], null); if (method.getReturnType() != types[i]) { throw new BulkBeanException("Specified type " + types[i] + " does not match declared type " + method.getReturnType(), i); } if (Modifier.isPrivate(method.getModifiers())) { throw new BulkBeanException("Property is private", i); } getters_out[i] = method; } if (setters[i] != null) { Method method = ReflectUtils.findDeclaredMethod(target, setters[i], new Class[]{ types[i] }); if (Modifier.isPrivate(method.getModifiers()) ){ throw new BulkBeanException("Property is private", i); } setters_out[i] = method; } } } catch (NoSuchMethodException e) { throw new BulkBeanException("Cannot find specified property", i); } } }