org.impalaframework.spring.module.loader.BaseApplicationContextLoader.java Source code

Java tutorial

Introduction

Here is the source code for org.impalaframework.spring.module.loader.BaseApplicationContextLoader.java

Source

/*
 * Copyright 2007-2010 the original author or authors.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

package org.impalaframework.spring.module.loader;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.impalaframework.exception.ConfigurationException;
import org.impalaframework.module.ModuleDefinition;
import org.impalaframework.module.loader.ModuleLoaderRegistry;
import org.impalaframework.module.runtime.ModuleRuntimeUtils;
import org.impalaframework.module.spi.Application;
import org.impalaframework.module.spi.ModuleLoader;
import org.impalaframework.spring.module.ApplicationContextLoader;
import org.impalaframework.spring.module.DelegatingContextLoader;
import org.impalaframework.spring.module.SpringModuleLoader;
import org.impalaframework.util.ObjectUtils;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinitionReader;
import org.springframework.beans.factory.support.BeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;

/**
 * @author Phil Zoio
 */
public class BaseApplicationContextLoader implements ApplicationContextLoader {

    private static Log logger = LogFactory.getLog(BaseApplicationContextLoader.class);

    private ModuleLoaderRegistry moduleLoaderRegistry;

    private DelegatingContextLoaderRegistry delegatingContextLoaderRegistry;

    public BaseApplicationContextLoader() {
    }

    public ConfigurableApplicationContext loadContext(Application application, ClassLoader classLoader,
            ModuleDefinition definition, ApplicationContext parent) {

        Assert.notNull(moduleLoaderRegistry, ModuleLoaderRegistry.class.getName() + " cannot be null");
        Assert.notNull(delegatingContextLoaderRegistry,
                DelegatingContextLoaderRegistry.class.getName() + " cannot be null");
        ConfigurableApplicationContext context = null;

        final ModuleLoader loader = moduleLoaderRegistry
                .getModuleLoader(ModuleRuntimeUtils.getModuleLoaderKey(definition), false);
        final SpringModuleLoader moduleLoader = ObjectUtils.cast(loader, SpringModuleLoader.class);

        final DelegatingContextLoader delegatingLoader = delegatingContextLoaderRegistry
                .getDelegatingLoader(definition.getType());

        try {

            if (moduleLoader != null) {
                if (logger.isDebugEnabled())
                    logger.debug("Loading module " + definition + " using ModuleLoader " + moduleLoader);
                context = loadApplicationContext(application, classLoader, moduleLoader, parent, definition);

                final String applicationId = application.getId();
                moduleLoader.afterRefresh(applicationId, context, definition);
            } else if (delegatingLoader != null) {
                if (logger.isDebugEnabled())
                    logger.debug("Loading module " + definition + " using DelegatingContextLoader " + moduleLoader);
                context = delegatingLoader.loadApplicationContext(parent, definition);
            } else {
                throw new ConfigurationException(
                        "No " + ModuleLoader.class.getName() + " or " + DelegatingContextLoader.class.getName()
                                + " specified for module definition type " + definition.getType());
            }

        } finally {
            if (moduleLoader != null) {
                afterContextLoaded(definition, moduleLoader);
            }
        }

        return context;
    }

    /**
     * If {@link ApplicationContext} is an instance of
     * {@link ConfigurableApplicationContext}, then calls
     * {@link ConfigurableApplicationContext#close()}. Also, prior to this, if
     * module is associated with {@link SpringModuleLoader}, then
     * {@link SpringModuleLoader#beforeClose(String, ApplicationContext, ModuleDefinition)}
     * is called.
     */
    public void closeContext(String applicationId, ModuleDefinition moduleDefinition,
            ApplicationContext applicationContext) {

        Assert.notNull(moduleLoaderRegistry, ModuleLoaderRegistry.class.getName() + " cannot be null");
        final ModuleLoader loader = moduleLoaderRegistry
                .getModuleLoader(ModuleRuntimeUtils.getModuleLoaderKey(moduleDefinition), false);

        if (loader instanceof SpringModuleLoader) {
            SpringModuleLoader springModuleLoader = (SpringModuleLoader) loader;
            springModuleLoader.beforeClose(applicationId, applicationContext, moduleDefinition);
        }

        if (applicationContext instanceof ConfigurableApplicationContext) {
            ConfigurableApplicationContext configurableContext = (ConfigurableApplicationContext) applicationContext;
            configurableContext.close();
        }
    }

    protected void afterContextLoaded(ModuleDefinition definition, final ModuleLoader moduleLoader) {
    }

    private ConfigurableApplicationContext loadApplicationContext(Application application, ClassLoader classLoader,
            SpringModuleLoader moduleLoader, ApplicationContext parent, ModuleDefinition definition) {

        ClassLoader existing = ClassUtils.getDefaultClassLoader();

        try {
            Thread.currentThread().setContextClassLoader(classLoader);

            if (logger.isDebugEnabled())
                logger.debug("Setting class loader to " + classLoader);

            ConfigurableApplicationContext context = moduleLoader.newApplicationContext(application, parent,
                    definition, classLoader);
            ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
            addBeanPostProcessors(application, definition, beanFactory);

            final String applicationId = application.getId();
            BeanDefinitionReader reader = moduleLoader.newBeanDefinitionReader(applicationId, context, definition);

            if (reader != null) {
                //if this is null, then we assume moduleLoader or refresh takes care of this

                if (reader instanceof AbstractBeanDefinitionReader) {
                    ((AbstractBeanDefinitionReader) reader).setBeanClassLoader(classLoader);
                }

                final Resource[] resources = moduleLoader.getSpringConfigResources(applicationId, definition,
                        classLoader);
                reader.loadBeanDefinitions(resources);
            }

            moduleLoader.handleRefresh(applicationId, context, definition);
            return context;
        } finally {
            Thread.currentThread().setContextClassLoader(existing);
        }
    }

    protected void addBeanPostProcessors(Application application, ModuleDefinition definition,
            ConfigurableListableBeanFactory beanFactory) {
    }

    /* **************************** injected setters ************************** */

    public void setModuleLoaderRegistry(ModuleLoaderRegistry moduleLoaderRegistry) {
        this.moduleLoaderRegistry = moduleLoaderRegistry;
    }

    public void setDelegatingContextLoaderRegistry(
            DelegatingContextLoaderRegistry delegatingContextLoaderRegistry) {
        this.delegatingContextLoaderRegistry = delegatingContextLoaderRegistry;
    }

}