architecture.ee.component.core.lifecycle.BootstrapImpl.java Source code

Java tutorial

Introduction

Here is the source code for architecture.ee.component.core.lifecycle.BootstrapImpl.java

Source

/*
 * Copyright 2012 Donghyuck, Son
 *
 * 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 architecture.ee.component.core.lifecycle;

import java.lang.ref.WeakReference;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantLock;

import javax.servlet.ServletContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.access.BeanFactoryReference;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.access.ContextSingletonBeanFactoryLocator;
import org.springframework.web.context.ContextLoader;

import architecture.common.exception.ComponentNotFoundException;
import architecture.common.lifecycle.ApplicationProperties;
import architecture.common.lifecycle.ConfigService;
import architecture.common.lifecycle.Repository;
import architecture.common.lifecycle.State;
import architecture.common.lifecycle.bootstrap.Bootstrap;
import architecture.common.lifecycle.service.AdminService;
import architecture.common.util.L10NUtils;
import architecture.ee.spring.lifecycle.SpringAdminService;
import architecture.ee.util.ApplicationConstants;

/**
 * this bootstrap ... for everything.
 * 
 * 
 * @author donghyuck
 */
public class BootstrapImpl implements Bootstrap.Implementation {

    private Log log = LogFactory.getLog(getClass());

    private static final String BOOTSTRAP_CONTEXT_KEY = "default-services-context";

    private Map<Class<?>, WeakReference<?>> references = Collections
            .synchronizedMap(new HashMap<Class<?>, WeakReference<?>>());

    private RepositoryImpl repository = new RepositoryImpl();

    private final ReentrantLock lock = new ReentrantLock();

    private final AtomicBoolean initialized = new AtomicBoolean(false);

    private final AtomicBoolean bootstrapAdminServiceEnabled = new AtomicBoolean(false);

    private String bootstrapFactoryKey;

    public ConfigurableApplicationContext getBootstrapApplicationContext() {
        try {
            //  ?  ? ?  ?  ..
            if (repository.getState() == State.INITIALIZED && !initialized.getAndSet(true)) {
                ApplicationProperties properties = repository.getSetupApplicationProperties();
                Collection<String> names = properties.getPropertyNames();
                if (log.isDebugEnabled()) {
                    log.debug(L10NUtils.getMessage("003050"));
                    for (String name : names) {
                        log.debug(L10NUtils.format("003053", name, properties.get(name)));
                    }
                }
                boolean setupComplete = properties.getBooleanProperty(ApplicationConstants.SETUP_COMPLETE_PROP_NAME,
                        false);
                bootstrapFactoryKey = properties.getStringProperty(ApplicationConstants.BOOTSTRAP_CONTEXT_PROP_NAME,
                        BOOTSTRAP_CONTEXT_KEY);
                if (log.isDebugEnabled()) {
                    log.info(L10NUtils.format("003008", setupComplete));
                    log.info(L10NUtils.format("003009", bootstrapFactoryKey));
                }
            }
            BeanFactoryReference parentContextRef = ContextSingletonBeanFactoryLocator.getInstance()
                    .useBeanFactory(bootstrapFactoryKey);
            ConfigurableApplicationContext context = (ConfigurableApplicationContext) parentContextRef.getFactory();
            return context;
        } catch (Throwable e) {
            log.error(L10NUtils.getMessage("002402"), e);
            return null;
        }
    }

    @SuppressWarnings("unchecked")
    public <T> T getBootstrapComponent(Class<T> requiredType) throws ComponentNotFoundException {
        if (requiredType == null) {
            throw new ComponentNotFoundException();
        }

        if (requiredType == Repository.class) {
            lock.lock();
            try {
                if (repository.getState() != State.INITIALIZED) {
                    repository.initialize();
                }
            } catch (Exception e) {

            } finally {
                lock.unlock();
            }
            return (T) repository;
        }
        if (references.get(requiredType) == null) {
            try {
                if (getBootstrapApplicationContext() == null) {
                    throw new IllegalStateException(L10NUtils.getMessage("003051"));
                }
                if (ContextLoader.getCurrentWebApplicationContext() != null) {
                    log.debug("searching in current web application context");
                    references.put(requiredType, new WeakReference<T>(
                            ContextLoader.getCurrentWebApplicationContext().getBean(requiredType)));
                } else {
                    log.debug("searching in bootstrap application context");
                    references.put(requiredType,
                            new WeakReference<T>(getBootstrapApplicationContext().getBean(requiredType)));
                }
            } catch (BeansException e) {
                throw new ComponentNotFoundException(L10NUtils.format("003052", requiredType.getName()), e);
            }
        }
        return (T) references.get(requiredType).get();
    }

    public void boot(ServletContext servletContext) {
        lock.lock();
        try {
            log.debug("checking repository state:" + getState());
            if (repository.getState() != State.INITIALIZED) {
                ((RepositoryImpl) repository).setServletContext(servletContext);
            }

            // 1. admin service  bootstrap ?   : DOTO
            AdminService adminService = getBootstrapComponent(AdminService.class);
            bootstrapAdminServiceEnabled.set(true);
            if (adminService instanceof SpringAdminService) {
                ((SpringAdminService) adminService).setServletContext(servletContext);
            }
            adminService.start();
        } catch (ComponentNotFoundException e) {
            log.debug("no adminservice.");
            ContextLoader contextLoader = getBootstrapComponent(ContextLoader.class);
            contextLoader.initWebApplicationContext(servletContext);
        } finally {
            lock.unlock();
        }
    }

    public AdminService getAdminService() throws ComponentNotFoundException {

        if (bootstrapAdminServiceEnabled.get()) {
            return getBootstrapComponent(AdminService.class);
        } else {
            if (initialized.get()) {
                try {
                    return ContextLoader.getCurrentWebApplicationContext().getBean(AdminService.class);
                } catch (BeansException e1) {
                    throw new ComponentNotFoundException(e1);
                }
            } else {
                throw new ComponentNotFoundException();
            }
        }
    }

    public void shutdown(ServletContext servletContext) {
        lock.lock();
        try {
            if (bootstrapAdminServiceEnabled.get()) {
                AdminService adminService = getAdminService();
                adminService.stop();
                adminService.destroy();
            } else {
                ContextLoader contextLoader = getBootstrapComponent(ContextLoader.class);
                contextLoader.closeWebApplicationContext(servletContext);
            }
        } finally {
            initialized.set(false);
            lock.unlock();
        }
    }

    @SuppressWarnings("unchecked")
    @Deprecated
    public boolean isBootstrapComponentAvailable(Class serviceClass) {
        try {
            getBootstrapComponent(serviceClass);
        } catch (ComponentNotFoundException e) {
            return false;
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    public State getState() {
        try {
            if (initialized.get()) {
                return getAdminService().getState();
            } else {
                return repository.getState();
            }
        } catch (ComponentNotFoundException e) {
            return repository.getState();
        }
    }

}