Package net.sourceforge.javautil.interceptor.type.cjcw

Source Code of net.sourceforge.javautil.interceptor.type.cjcw.InterceptorProxyTypeCJCW

package net.sourceforge.javautil.interceptor.type.cjcw;

import java.lang.reflect.Method;
import java.util.List;

import net.sourceforge.javautil.bytecode.BytecodeCompiler;
import net.sourceforge.javautil.bytecode.api.BytecodeContext;
import net.sourceforge.javautil.bytecode.api.IBytecodeResolvable;
import net.sourceforge.javautil.bytecode.api.MethodDescriptor;
import net.sourceforge.javautil.bytecode.api.TypeDescriptor;
import net.sourceforge.javautil.bytecode.api.TypeMemberAccess.Scope;
import net.sourceforge.javautil.bytecode.api.type.method.BytecodeBlock;
import net.sourceforge.javautil.bytecode.api.type.method.IBytecodeConstructor;
import net.sourceforge.javautil.bytecode.api.type.method.BytecodeConstructorBase;
import net.sourceforge.javautil.bytecode.api.type.method.BytecodeContextMethod;
import net.sourceforge.javautil.bytecode.api.type.method.IBytecodeMethod;
import net.sourceforge.javautil.bytecode.api.type.method.BytecodeMethodConcrete;
import net.sourceforge.javautil.common.CollectionUtil;
import net.sourceforge.javautil.interceptor.IInterceptedInstanceWrapper;
import net.sourceforge.javautil.interceptor.IInterceptorManager;
import net.sourceforge.javautil.interceptor.IInterceptorManipulator;
import net.sourceforge.javautil.interceptor.type.InterceptorProxyTypeInterceptor;

/**
* A proxy type that wraps an instance of it's super class overriding public methods and then proxying to an underlying instance.
*
* @author elponderador
* @author $Author$
* @version $Id$
*/
public class InterceptorProxyTypeCJCW extends InterceptorProxyTypeInterceptor {
 
  public static final String TARGET_FIELD_NAME = "target";

  public InterceptorProxyTypeCJCW(BytecodeCompiler compiler, List<IInterceptorManipulator> abilities, Class type, String name) {
    super(compiler, abilities, type, name);
    this.addInstanceField(TARGET_FIELD_NAME, IInterceptedInstanceWrapper.class, Scope.Private, true);
  }

  @Override public void addProxyConstructors() {
    InterceptorProxyConstructor apc = new InterceptorProxyConstructor(abilities);
    for (IBytecodeConstructor constructor : getSuperType().getDeclaredConstructors()) {
      if (constructor.getAccess().getScope() == Scope.Public) {
        TypeDescriptor[] parameters = constructor.getDescriptor().getParameters();
        parameters = CollectionUtil.insert(parameters, 0, TypeDescriptor.getFor(IInterceptorManager.class), TypeDescriptor.getFor(IInterceptedInstanceWrapper.class));
        BytecodeConstructorBase pc = this.addConstructor(Scope.Public, constructor.isVarArgs(), parameters);
        pc.copyAnnotations(constructor);
        pc.setMethodBody(apc);
      }
    }
  }
 
  @Override public void addProxyMethods() {
    final InterceptorProxyMethod apm = new InterceptorProxyMethod();
    BytecodeBlock apmb = new BytecodeBlock() {
     
      @Override protected void writeInstructions(BytecodeContextMethod context) {
        apm.write(context);
      }
     
    };
   
    IBytecodeResolvable st = getSuperType();
    while (st != null && !"java.lang.Object".equals( st.getType().getClassName() )) {
      for (IBytecodeMethod method : st.getDeclaredMethods()) {
        if (method.getAccess().isStatic() || method.getAccess().getScope() != Scope.Public) continue;
       
        BytecodeMethodConcrete bmc = this.addMethod(method.getName(), Scope.Public, false, true, method.getDescriptor());
        bmc.copyAnnotations(method);
        bmc.setMethodBody(apmb);
      }
     
      st = st.getSuperType();
    }
   
    try {
      Method toString = type.getMethod("toString");
      if (toString.getDeclaringClass() == Object.class) {
        this.addMethod("toString", Scope.Public, false, true, new MethodDescriptor(toString))
          .setMethodBody(new BytecodeBlock() {
           
            @Override protected void writeInstructions(BytecodeContextMethod context) {
              context.returnValue(context.createInvocation(
                context.getThisField(TARGET_FIELD_NAME).createInvocation(context, "get", context.resolve("this")), "toString")
              );
            }
           
          });
      }
    } catch (NoSuchMethodException e) {}   
  }

}
TOP

Related Classes of net.sourceforge.javautil.interceptor.type.cjcw.InterceptorProxyTypeCJCW

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.