package org.springmodules.ant.util; import java.util.HashMap; import java.util.Map; import org.apache.tools.ant.BuildException; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.HierarchicalBeanFactory; import org.springframework.beans.factory.access.SingletonBeanFactoryLocator; import org.springframework.context.ConfigurableApplicationContext; /** * Utility class to load a (possibly hierarchical) BeanFactory in the context * of an Ant task or type. * * @author Dave Syer * */ public abstract class BeanFactoryLoader { /** * The default location of a resource (or set of resources) containing BeanFactory * bean definitions. */ public static String DEFAULT_CONTEXT_REF = "classpath*:beanRefContext.xml"; private static Map factoryCache = new HashMap(); /** * Load a BeanFactory from the default context and given factoryKey. * @param factoryKey bean name idenitifying a BeanFactory instance in the contextRef. * @return BeanFactory instance if it exists, null if not. * @throws BuildException if the BeanFactory cannot be initialized. */ public static BeanFactory getBeanFactory(String factoryKey) throws BuildException { return getBeanFactory(DEFAULT_CONTEXT_REF, factoryKey); } /** * Load a BeanFactory from the given context and factoryKey. * @param contextRef location of context bean definitions (e.g. classpath*:beanRefContext.xml). * @param factoryKey bean name idenitifying a BeanFactory instance in the contextRef. * @return BeanFactory instance if it exists, null if not. * @throws BuildException if the BeanFactory cannot be initialized. */ public static BeanFactory getBeanFactory(String contextRef, String factoryKey) throws BuildException { String cacheKey = contextRef + factoryKey; BeanFactory beanFactory = (BeanFactory)factoryCache.get(cacheKey); // Try to cache factories as we load them... if (beanFactory!=null) return beanFactory; try { beanFactory = SingletonBeanFactoryLocator.getInstance( contextRef).useBeanFactory(factoryKey) .getFactory(); refresh(beanFactory); } catch (BeansException e) { throw new BuildException("Cannot locate the bean factory: [" + contextRef + "].[" + factoryKey + "]", e); } factoryCache.put(cacheKey, beanFactory); return beanFactory; } private static void refresh(BeanFactory beanFactory) { // Refresh the parent first (recursively)... if (beanFactory instanceof HierarchicalBeanFactory) { refresh(((HierarchicalBeanFactory)beanFactory).getParentBeanFactory()); } if (beanFactory instanceof ConfigurableApplicationContext) { ((ConfigurableApplicationContext)beanFactory).refresh(); } } }