Package cn.wensiqun.asmsupport.operators.util

Source Code of cn.wensiqun.asmsupport.operators.util.OperatorFactory

package cn.wensiqun.asmsupport.operators.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import org.apache.commons.lang3.ArrayUtils;

import cn.wensiqun.asmsupport.block.ProgramBlock;
import cn.wensiqun.asmsupport.exception.ASMSupportException;
import cn.wensiqun.asmsupport.operators.AbstractOperator;
import cn.wensiqun.asmsupport.operators.listener.ReturnOperatoInCatchWithFinallyListener;

public abstract class OperatorFactory {
 
  private static List<NewOperatorListener> oneTimeListeners = new Vector<NewOperatorListener>();
 
  private static List<NewOperatorListener> multiTimeListeners = new Vector<NewOperatorListener>();

  static{
    NewOperatorListener cfListener = new ReturnOperatoInCatchWithFinallyListener();
        OperatorFactory.addMultiTimeListener(cfListener);
  }
 
  public static void resetListener(){
    //oneTimeListeners = new Vector<NewOperatorListener>();
    //multiTimeListeners = new Vector<NewOperatorListener>();
  }
 
  public static void addOneTimeListener(NewOperatorListener linstener){
    oneTimeListeners.add(linstener);
  }

  public static boolean removeOneTimeListener(NewOperatorListener linstener){
    return oneTimeListeners.remove(linstener);
  }
 
  public static void addMultiTimeListener(NewOperatorListener linstener){
    multiTimeListeners.add(linstener);
  }
 
  public static boolean removeMultiTimeListener(NewOperatorListener linstener){
    return multiTimeListeners.remove(linstener);
  }

  /**
   * 通过反射创建字节码操作
   * @param <T>
   * @param clazz
   * @param parameterTypes
   * @param arguments
   * @return
   */
  public static <T extends AbstractOperator> T newOperator(Class<T> clazz, Class<?>[] parameterTypes, Object... arguments){
    if(parameterTypes != null && arguments != null){
      if(!ArrayUtils.isSameLength(parameterTypes, arguments)){//parameterTypes.length != arguments.length){
        throw new ASMSupportException();
      }
    }else if(ArrayUtils.isEmpty(parameterTypes) || ArrayUtils.isEmpty(arguments)){
      throw new NullPointerException();
    }else if(!ProgramBlock.class.equals(parameterTypes[0])){
        throw new ASMSupportException("first argument type must be ProgramBlock")
    }
   
    ProgramBlock executeBlock = (ProgramBlock) arguments[0];
   
    executeBlock.tiggerTryCatchPrepare();
    try {
      //触发一次性任务的监听器
      List<NewOperatorListener> foundOneTimeListeners = null;
      for(NewOperatorListener linstener : oneTimeListeners){
        linstener.setExecuteBlock(executeBlock);
        linstener.setOperatorClass(clazz);
        linstener.setParameterTypes(parameterTypes);
        linstener.setArguments(arguments);
       
        if(linstener.triggerCondition()){
          if(foundOneTimeListeners == null){
            foundOneTimeListeners = new ArrayList<NewOperatorListener>();
          }
          linstener.beforeNew();
          foundOneTimeListeners.add(linstener);
          break;
        }else{
          linstener.setOperatorClass(null);
          linstener.setParameterTypes(null);
          linstener.setArguments(null);
        }
      }

      //触发多次性任务的监听器
      List<NewOperatorListener> foundMultiTimeListeners = null;
      for(NewOperatorListener linstener : multiTimeListeners){
        linstener.setExecuteBlock((ProgramBlock)arguments[0]);
        linstener.setOperatorClass(clazz);
        linstener.setParameterTypes(parameterTypes);
        linstener.setArguments(arguments);
       
        if(linstener.triggerCondition()){
          if(foundMultiTimeListeners == null){
            foundMultiTimeListeners = new ArrayList<NewOperatorListener>();
          }
          linstener.beforeNew();
          foundMultiTimeListeners.add(linstener);
          break;
        }else{
          linstener.setOperatorClass(null);
          linstener.setParameterTypes(null);
          linstener.setArguments(null);
        }
      }
     
      Constructor<T> constructor = parameterTypes == null ? clazz.getDeclaredConstructor() : clazz.getDeclaredConstructor(parameterTypes);
      boolean accessable = constructor.isAccessible();
      constructor.setAccessible(true);
      T instance = parameterTypes == null ? constructor.newInstance() : constructor.newInstance(arguments);
      constructor.setAccessible(accessable);
     
      Method checkAsArgument = AbstractOperator.class.getDeclaredMethod("checkAsArgument");
      accessable = checkAsArgument.isAccessible();
      checkAsArgument.setAccessible(true);
      checkAsArgument.invoke(instance);
      checkAsArgument.setAccessible(accessable);
     
      instance.checkUnreachableCode();
     
      instance.prepare();
     
      if(foundOneTimeListeners != null){
        for(NewOperatorListener linstener : foundOneTimeListeners){
          linstener.afterNew(instance);
          oneTimeListeners.remove(linstener);
        }
      }
     
      if(foundMultiTimeListeners != null){
        for(NewOperatorListener linstener : foundMultiTimeListeners){
          linstener.afterNew(instance);
          linstener.setOperatorClass(null);
          linstener.setParameterTypes(null);
          linstener.setArguments(null);
       
      }
     
      return instance;
    } catch (NoSuchMethodException e) {
      e.printStackTrace();
    } catch (InstantiationException e) {
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      e.printStackTrace();
    } catch (InvocationTargetException e) {
      if(e.getTargetException() instanceof ASMSupportException){
        throw (ASMSupportException)e.getTargetException();
      }else if(e.getTargetException() instanceof RuntimeException){
        throw (RuntimeException)e.getTargetException();
      }else{
        e.printStackTrace();
      }
    }
   
    return null;
  }

}
TOP

Related Classes of cn.wensiqun.asmsupport.operators.util.OperatorFactory

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.