content: package com.alibaba.smart.framework.engine.util;
  
  import java.lang.reflect.Constructor;
  import java.lang.reflect.InvocationTargetException;
  import java.util.Map;
  import java.util.concurrent.ConcurrentHashMap;
  import java.util.concurrent.locks.Lock;
  import java.util.concurrent.locks.ReentrantLock;
  
  import com.alibaba.smart.framework.engine.exception.EngineException;
  
  import com.esotericsoftware.reflectasm.ConstructorAccess;
  
  public abstract  class ClassUtil {
  
  
  
      private  static Map<Class,Object> objectMap = new ConcurrentHashMap<Class, Object>();
  
      private  static Map<String,Class> classMap = new ConcurrentHashMap<String, Class>();
  
      private static Lock lock = new ReentrantLock();
  
      public static ClassLoader getContextClassLoader() {
          return  Thread.currentThread().getContextClassLoader();
      }
  
      public static ClassLoader getFallbackClassLoader() {
          return ClassUtil.class.getClassLoader();
      }
  
      public static Object createNewInstance(Class clazz) {
  
              ConstructorAccess access = ConstructorAccess.get(clazz);
              return access.newInstance();
      }
  
  
      public static Object createOrGetInstance(Class clazz) {
  
              Object object = objectMap.get(clazz);
  
              if(object == null){
                  ConstructorAccess access = ConstructorAccess.get(clazz);
                  object  = access.newInstance();
                  objectMap.put(clazz,object);
                  return object;
              }else{
                  return object;
              }
  
      }
  
      public static Object createOrGetInstance(String className) throws EngineException {
          Class clazz;
          try {
  
              clazz = classMap.get(className);
  
              if(null == clazz){
                  clazz = getContextClassLoader().loadClass(className);
                  classMap.put(className,clazz);
              }
  
          } catch (ClassNotFoundException e) {
              throw new EngineException(e);
          }
  
          return createOrGetInstance(clazz);
  
  
  
      }
  
  
      public static Constructor getConstruct(Class clazz, Class... argTypes) throws EngineException {
          String className = clazz.getName();
  
          try {
              Constructor constructor = clazz.getConstructor(argTypes);
              return constructor;
          } catch (NoSuchMethodException e) {
              throw new EngineException("Unable to load class " + className + ". Initial cause was " + e.getMessage(), e);
          } catch (SecurityException e) {
              throw new EngineException("Unable to load class " + className + ". Initial cause was " + e.getMessage(), e);
          } catch (IllegalArgumentException e) {
              throw new EngineException("Unable to load class " + className + ". Initial cause was " + e.getMessage(), e);
          }
  
      }
  
  
      public static Object createNewInstance(Constructor constructor, Object... args) throws EngineException {
          String className =  constructor.getClass().getName();
  
          try {
              Object newInstance = constructor.newInstance(args);
              return newInstance;
  
          } catch (IllegalAccessException e) {
              throw new EngineException("Unable to load class " + className + ". Initial cause was " + e.getMessage(), e);
          } catch (InstantiationException e) {
              throw new EngineException("Unable to load class " + className + ". Initial cause was " + e.getMessage(), e);
          } catch (SecurityException e) {
              throw new EngineException("Unable to load class " + className + ". Initial cause was " + e.getMessage(), e);
          } catch (IllegalArgumentException e) {
              throw new EngineException("Unable to load class " + className + ". Initial cause was " + e.getMessage(), e);
          } catch (InvocationTargetException e) {
              throw new EngineException("Unable to load class " + className + ". Initial cause was "
                  + e.getCause().getMessage(), e.getCause());
          }
      }
  
  
  
      public static Class loadClass(String className)  {
          Class clazz;
  
          try {
              clazz = Class.forName(className, true, getContextClassLoader());
          } catch (ClassNotFoundException e) {
              //   fallback
              try {
                  clazz = Class.forName(className, true, getFallbackClassLoader());
              } catch (ClassNotFoundException e1) {
                  throw new EngineException("Unable to load class " + className + ". Initial cause was "
                      + e.getCause().getMessage(), e.getCause());
              }
          }
  
          return clazz;
      }
  
  
  
  }
  