Пример #1
0
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());
    }
  }
}
Пример #2
0
  public static class Generator extends AbstractClassGenerator {
    private static final Source SOURCE = new Source(MethodDelegate.class.getName());
    private static final Type METHOD_DELEGATE =
        TypeUtils.parseType("net.sf.cglib.reflect.MethodDelegate");
    private static final Signature NEW_INSTANCE =
        new Signature("newInstance", METHOD_DELEGATE, new Type[] {Constants.TYPE_OBJECT});

    private Object target;
    private Class targetClass;
    private String methodName;
    private Class iface;

    public Generator() {
      super(SOURCE);
    }

    public void setTarget(Object target) {
      this.target = target;
      this.targetClass = target.getClass();
    }

    public void setTargetClass(Class targetClass) {
      this.targetClass = targetClass;
    }

    public void setMethodName(String methodName) {
      this.methodName = methodName;
    }

    public void setInterface(Class iface) {
      this.iface = iface;
    }

    protected ClassLoader getDefaultClassLoader() {
      return targetClass.getClassLoader();
    }

    protected ProtectionDomain getProtectionDomain() {
      return ReflectUtils.getProtectionDomain(targetClass);
    }

    public MethodDelegate create() {
      setNamePrefix(targetClass.getName());
      Object key = KEY_FACTORY.newInstance(targetClass, methodName, iface);
      return (MethodDelegate) super.create(key);
    }

    protected Object firstInstance(Class type) {
      return ((MethodDelegate) ReflectUtils.newInstance(type)).newInstance(target);
    }

    protected Object nextInstance(Object instance) {
      return ((MethodDelegate) instance).newInstance(target);
    }

    public void generateClass(ClassVisitor v) throws NoSuchMethodException {
      Method proxy = ReflectUtils.findInterfaceMethod(iface);
      final Method method = targetClass.getMethod(methodName, proxy.getParameterTypes());
      if (!proxy.getReturnType().isAssignableFrom(method.getReturnType())) {
        throw new IllegalArgumentException("incompatible return types");
      }

      MethodInfo methodInfo = ReflectUtils.getMethodInfo(method);

      boolean isStatic = TypeUtils.isStatic(methodInfo.getModifiers());
      if ((target == null) ^ isStatic) {
        throw new IllegalArgumentException(
            "Static method " + (isStatic ? "not " : "") + "expected");
      }

      ClassEmitter ce = new ClassEmitter(v);
      CodeEmitter e;
      ce.begin_class(
          Constants.V1_2,
          Constants.ACC_PUBLIC,
          getClassName(),
          METHOD_DELEGATE,
          new Type[] {Type.getType(iface)},
          Constants.SOURCE_FILE);
      ce.declare_field(Constants.PRIVATE_FINAL_STATIC, "eqMethod", Constants.TYPE_STRING, null);
      EmitUtils.null_constructor(ce);

      // generate proxied method
      MethodInfo proxied = ReflectUtils.getMethodInfo(iface.getDeclaredMethods()[0]);
      int modifiers = Constants.ACC_PUBLIC;
      if ((proxied.getModifiers() & Constants.ACC_VARARGS) == Constants.ACC_VARARGS) {
        modifiers |= Constants.ACC_VARARGS;
      }
      e = EmitUtils.begin_method(ce, proxied, modifiers);
      e.load_this();
      e.super_getfield("target", Constants.TYPE_OBJECT);
      e.checkcast(methodInfo.getClassInfo().getType());
      e.load_args();
      e.invoke(methodInfo);
      e.return_value();
      e.end_method();

      // newInstance
      e = ce.begin_method(Constants.ACC_PUBLIC, NEW_INSTANCE, null);
      e.new_instance_this();
      e.dup();
      e.dup2();
      e.invoke_constructor_this();
      e.getfield("eqMethod");
      e.super_putfield("eqMethod", Constants.TYPE_STRING);
      e.load_arg(0);
      e.super_putfield("target", Constants.TYPE_OBJECT);
      e.return_value();
      e.end_method();

      // static initializer
      e = ce.begin_static();
      e.push(methodInfo.getSignature().toString());
      e.putfield("eqMethod");
      e.return_value();
      e.end_method();

      ce.end_class();
    }
  }
Пример #3
0
    public void generateClass(ClassVisitor v) throws NoSuchMethodException {
      Method proxy = ReflectUtils.findInterfaceMethod(iface);
      final Method method = targetClass.getMethod(methodName, proxy.getParameterTypes());
      if (!proxy.getReturnType().isAssignableFrom(method.getReturnType())) {
        throw new IllegalArgumentException("incompatible return types");
      }

      MethodInfo methodInfo = ReflectUtils.getMethodInfo(method);

      boolean isStatic = TypeUtils.isStatic(methodInfo.getModifiers());
      if ((target == null) ^ isStatic) {
        throw new IllegalArgumentException(
            "Static method " + (isStatic ? "not " : "") + "expected");
      }

      ClassEmitter ce = new ClassEmitter(v);
      CodeEmitter e;
      ce.begin_class(
          Constants.V1_2,
          Constants.ACC_PUBLIC,
          getClassName(),
          METHOD_DELEGATE,
          new Type[] {Type.getType(iface)},
          Constants.SOURCE_FILE);
      ce.declare_field(Constants.PRIVATE_FINAL_STATIC, "eqMethod", Constants.TYPE_STRING, null);
      EmitUtils.null_constructor(ce);

      // generate proxied method
      MethodInfo proxied = ReflectUtils.getMethodInfo(iface.getDeclaredMethods()[0]);
      int modifiers = Constants.ACC_PUBLIC;
      if ((proxied.getModifiers() & Constants.ACC_VARARGS) == Constants.ACC_VARARGS) {
        modifiers |= Constants.ACC_VARARGS;
      }
      e = EmitUtils.begin_method(ce, proxied, modifiers);
      e.load_this();
      e.super_getfield("target", Constants.TYPE_OBJECT);
      e.checkcast(methodInfo.getClassInfo().getType());
      e.load_args();
      e.invoke(methodInfo);
      e.return_value();
      e.end_method();

      // newInstance
      e = ce.begin_method(Constants.ACC_PUBLIC, NEW_INSTANCE, null);
      e.new_instance_this();
      e.dup();
      e.dup2();
      e.invoke_constructor_this();
      e.getfield("eqMethod");
      e.super_putfield("eqMethod", Constants.TYPE_STRING);
      e.load_arg(0);
      e.super_putfield("target", Constants.TYPE_OBJECT);
      e.return_value();
      e.end_method();

      // static initializer
      e = ce.begin_static();
      e.push(methodInfo.getSignature().toString());
      e.putfield("eqMethod");
      e.return_value();
      e.end_method();

      ce.end_class();
    }
Пример #4
0
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);
        }
    }
}