package h2o.common.thirdparty.spring.factory;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.ResolvableType;

import java.util.concurrent.locks.Lock;

public class SpringFactory implements BeanFactoryAware {
	
	private static final Lock lock = new java.util.concurrent.locks.ReentrantLock();

	private static volatile BeanFactory beanFactory;

	public  static void setStaticConfigPath(String... path) {
		lock.lock();
		try {
			beanFactory = new ClassPathXmlApplicationContext(path);
		} finally {
			lock.unlock();
		}	
	}
	
	public void setConfigPath(String... path) {
		setStaticConfigPath(path);
	}

    public void setBeanFactory(BeanFactory bf) throws BeansException {
        lock.lock();
        try {
            beanFactory = bf;
        } finally {
            lock.unlock();
        }
    }

    public static BeanFactory getBeanFactory()  {
        BeanFactory bf = beanFactory;
        if (bf == null) {
            lock.lock();
            try {
                bf = beanFactory;
                if (bf == null) {
                    setStaticConfigPath("/applicationContext.xml");
                    bf = beanFactory;
                }
            } finally {
                lock.unlock();
            }
        }
        return bf;
    }


	@SuppressWarnings("unchecked")
	public static <T> T getObject(String beanId) {
		
		return (T) getBeanFactory().getBean(beanId);
	}


	/*====== delegate =====*/


    public static Object getBean(String name) throws BeansException {
        return beanFactory.getBean(name);
    }

    public static <T> T getBean(String name, Class<T> requiredType) throws BeansException {
        return beanFactory.getBean(name, requiredType);
    }

    public static <T> T getBean(Class<T> requiredType) throws BeansException {
        return beanFactory.getBean(requiredType);
    }

    public static Object getBean(String name, Object... args) throws BeansException {
        return beanFactory.getBean(name, args);
    }

    public static <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {
        return beanFactory.getBean(requiredType, args);
    }

    public static boolean containsBean(String name) {
        return beanFactory.containsBean(name);
    }

    public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
        return beanFactory.isSingleton(name);
    }

    public static boolean isPrototype(String name) throws NoSuchBeanDefinitionException {
        return beanFactory.isPrototype(name);
    }

    public static boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException {
        return beanFactory.isTypeMatch(name, typeToMatch);
    }

    public static boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException {
        return beanFactory.isTypeMatch(name, typeToMatch);
    }

    public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
        return beanFactory.getType(name);
    }

    public static String[] getAliases(String name) {
        return beanFactory.getAliases(name);
    }



}

@@ -1789,33 +1789,36 @@
 %0A        return 
-b
+getB
 eanFactory.getBe
@@ -1803,32 +1803,34 @@
 n getBeanFactory
+()
 .getBean(name);%0A
@@ -1935,33 +1935,36 @@
 %0A        return 
-b
+getB
 eanFactory.getBe
@@ -1949,32 +1949,34 @@
 n getBeanFactory
+()
 .getBean(name, r
@@ -2082,33 +2082,36 @@
 %0A        return 
-b
+getB
 eanFactory.getBe
@@ -2096,32 +2096,34 @@
 n getBeanFactory
+()
 .getBean(require
@@ -2230,33 +2230,36 @@
 %0A        return 
-b
+getB
 eanFactory.getBe
@@ -2244,32 +2244,34 @@
 n getBeanFactory
+()
 .getBean(name, a
@@ -2385,33 +2385,36 @@
 %0A        return 
-b
+getB
 eanFactory.getBe
@@ -2403,24 +2403,26 @@
 tBeanFactory
+()
 .getBean(req
@@ -2507,33 +2507,36 @@
 %0A        return 
-b
+getB
 eanFactory.conta
@@ -2529,16 +2529,18 @@
 nFactory
+()
 .contain
@@ -2656,33 +2656,36 @@
 %0A        return 
-b
+getB
 eanFactory.isSin
@@ -2678,16 +2678,18 @@
 nFactory
+()
 .isSingl
@@ -2804,33 +2804,36 @@
 %0A        return 
-b
+getB
 eanFactory.isPro
@@ -2826,16 +2826,18 @@
 nFactory
+()
 .isProto
@@ -2980,33 +2980,36 @@
 %0A        return 
-b
+getB
 eanFactory.isTyp
@@ -2994,32 +2994,34 @@
 n getBeanFactory
+()
 .isTypeMatch(nam
@@ -3163,33 +3163,36 @@
 %0A        return 
-b
+getB
 eanFactory.isTyp
@@ -3185,16 +3185,18 @@
 nFactory
+()
 .isTypeM
@@ -3321,33 +3321,36 @@
 %0A        return 
-b
+getB
 eanFactory.getTy
@@ -3339,24 +3339,26 @@
 tBeanFactory
+()
 .getType(nam
@@ -3436,17 +3436,20 @@
  return 
-b
+getB
 eanFacto
@@ -3450,16 +3450,18 @@
 nFactory
+()
 .getAlia

fix bug SpringFactory委托方法没有检查是否初始化