Package org.apache.openejb.spring

Source Code of org.apache.openejb.spring.OpenEJB

/**
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.openejb.spring;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
import javax.annotation.PostConstruct;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.transaction.TransactionManager;

import org.apache.openejb.Container;
import org.apache.openejb.DeploymentInfo;
import org.apache.openejb.OpenEJBException;
import org.apache.openejb.assembler.classic.Assembler;
import org.apache.openejb.assembler.classic.ContainerInfo;
import org.apache.openejb.assembler.classic.ProxyFactoryInfo;
import org.apache.openejb.assembler.classic.ResourceInfo;
import org.apache.openejb.assembler.classic.SecurityServiceInfo;
import org.apache.openejb.assembler.classic.ServiceInfo;
import org.apache.openejb.assembler.classic.TransactionServiceInfo;
import org.apache.openejb.assembler.dynamic.PassthroughFactory;
import org.apache.openejb.config.ConfigurationFactory;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.spi.ContainerSystem;
import org.apache.openejb.spi.SecurityService;
import org.apache.openejb.util.LogCategory;
import org.apache.openejb.util.Logger;
import org.apache.openejb.util.OpenEjbVersion;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

@Exported
public class OpenEJB implements ApplicationContextAware {
    private static Logger logger = Logger.getInstance(LogCategory.OPENEJB_STARTUP, "org.apache.openejb.util.resources");

    /**
     * Properties added to the OpenEJB SystemInstance on startup.
     */
    private final Properties properties = new Properties();

    /**
     * The TransactionManager to be used by the OpenEJB server, or null for the
     * default TransactionManager.
     */
    private TransactionManager transactionManager;

    /**
     * The SecurityService to be used by the OpenEJB server, or null for the
     * default SecurityService.
     */
    private SecurityService securityService;

    /**
     * Containers to add to the OpenEJB server.
     */
    private final Collection<ContainerProvider> containers = new ArrayList<ContainerProvider>();

    /**
     * Resources to add to the OpenEJB server.
     */
    private final Collection<ResourceProvider> resources = new ArrayList<ResourceProvider>();

    /**
     * Should the beans in the Spring context be imported into OpenEJB as resources?
     */
    private boolean importContext = true;

    /**
     * Is this bean starting?
     */
    private boolean starting;

    /**
     * While OpenEJB is starting any applications that are deployed are queued up until startup is complete.
     */
    private final List<AbstractApplication> applicationsToDeploy = new ArrayList<AbstractApplication>();

    /**
     * The application context to scan when importing Beans.
     */
    private ApplicationContext applicationContext;

    /**
     * The IDs of the resources we have already imported
     */
    private final Set<String> importedResourceIds = new TreeSet<String>();

    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties.clear();
        this.properties.putAll(properties);
    }

    public TransactionManager getTransactionManager() {
        return transactionManager;
    }

    public void setTransactionManager(TransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }

    public SecurityService getSecurityService() {
        return securityService;
    }

    public void setSecurityService(SecurityService securityService) {
        this.securityService = securityService;
    }

    public Collection<ContainerProvider> getContainers() {
        return containers;
    }

    public void setContainers(Collection<? extends ContainerProvider> containers) {
        this.containers.clear();
        this.containers.addAll(containers);
    }

    public Collection<ResourceProvider> getResources() {
        return resources;
    }

    public void setResources(Collection<? extends ResourceProvider> resources) {
        this.resources.clear();
        this.resources.addAll(resources);
    }

    public boolean isImportContext() {
        return importContext;
    }

    public void setImportContext(boolean importContext) {
        this.importContext = importContext;
    }

    public Context getInitialContext() throws NamingException {
        if (!org.apache.openejb.OpenEJB.isInitialized()) {
            throw new IllegalStateException("Not started");
        }

        Context context = new org.apache.openejb.core.ivm.naming.InitContextFactory().getInitialContext(properties);
        return context;
    }

    public boolean isStarting() {
        return starting;
    }

    public boolean isStarted() {
        return SystemInstance.get().getComponent(ContainerSystem.class) != null;
    }

    @PostConstruct
    public void start() throws OpenEJBException {
        // Transaction mananager and system instance can only be set once per SystemInstance (one per ClassLoader)
        if (isStarted()) {
            if (transactionManager != null) {
                throw new OpenEJBException("TransactionManager can not be set because OpenEJB has already been initalized");
            }
            if (securityService != null) {
                throw new OpenEJBException("SecurityService can not be set because OpenEJB has already been initalized");
            }
        }

        //
        // Is this bean already starting?  This helps avoid anoying spring loop backs.
        //
        if (starting) {
            throw new OpenEJBException("OpenEJB already starting");
        }
        starting = true;

        //
        // System Instance
        //
        SystemInstance system = SystemInstance.get();
        system.getProperties().putAll(properties);

        // do not deploy applications in claspath
        system.setProperty("openejb.deployments.classpath", "false");

        // we are in embedded mode
        system.setProperty("openejb.embedded", "true");

        //
        // Add TransactionManager and SecurityService to OpenEJB
        //
        ConfigurationFactory configurationFactory = new ConfigurationFactory();
        Assembler assembler;
        if (isStarted()) {
            assembler = SystemInstance.get().getComponent(Assembler.class);
        } else {
            //
            // Startup message
            //
            OpenEjbVersion versionInfo = OpenEjbVersion.get();

            if (properties.getProperty("openejb.nobanner") == null) {
                System.out.println("Apache OpenEJB " + versionInfo.getVersion() + "    build: " + versionInfo.getDate() + "-" + versionInfo.getTime());
                System.out.println("" + versionInfo.getUrl());
            }

            Logger logger2 = Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources");
            logger2.info("startup.banner", versionInfo.getUrl(), new Date(), versionInfo.getCopyright(),
                    versionInfo.getVersion(), versionInfo.getDate(), versionInfo.getTime());

            logger.info("openejb.home = " + SystemInstance.get().getHome().getDirectory().getAbsolutePath());
            logger.info("openejb.base = " + SystemInstance.get().getBase().getDirectory().getAbsolutePath());

            Properties props = new Properties(SystemInstance.get().getProperties());

            if (properties.isEmpty()) {
                logger.debug("startup.noInitializationProperties");
            } else {
                props.putAll(properties);
            }

            //
            // Assembler
            //
            assembler = new Assembler();
            assembler.createProxyFactory(configurationFactory.configureService(ProxyFactoryInfo.class));

            //
            // Transaction Manager
            //
            TransactionManager transactionManager = getTransactionManager();
            if (transactionManager == null) {
                transactionManager = getBeanForType(applicationContext, TransactionManager.class);
            }
            if (transactionManager != null) {
                TransactionServiceInfo info = initPassthrough(new TransactionServiceInfo(), "TransactionManager", transactionManager);
                assembler.createTransactionManager(info);
            }

            //
            // Security Service
            //
            SecurityService securityService = getSecurityService();
            if (securityService == null) {
                securityService = getBeanForType(applicationContext, SecurityService.class);
            }
            if (securityService != null) {
                SecurityServiceInfo info = initPassthrough(new SecurityServiceInfo(), "SecurityService", securityService);
                assembler.createSecurityService(info);
            }
        }

        //
        // Resources
        //
        for (Object resourceProvider : applicationContext.getBeansOfType(ResourceProvider.class).values()) {
            resources.add((ResourceProvider) resourceProvider);
        }
        for (ResourceProvider resourceProvider : getResources()) {
            ResourceInfo info = configurationFactory.configureService(resourceProvider.getResourceDefinition(), ResourceInfo.class);
            importedResourceIds.add(info.id);
            assembler.createResource(info);
        }
        if (isImportContext() && applicationContext != null) {
            for (String beanName : applicationContext.getBeanDefinitionNames()) {
                if (!importedResourceIds.contains(beanName)) {
                    Class beanType = applicationContext.getType(beanName);
                    Class factoryType = applicationContext.getType("&" + beanName);
                    if (isImportableType(beanType, factoryType)) {
                        SpringReference factory = new SpringReference(applicationContext, beanName, beanType);

                        ResourceInfo info = initPassthrough(beanName, new ResourceInfo(), "Resource", factory);
                        info.types = getTypes(beanType);
                        assembler.createResource(info);
                    }
                }
            }
        }

        //
        // Containers
        //
        for (Object containerProvider : applicationContext.getBeansOfType(ContainerProvider.class).values()) {
            containers.add((ContainerProvider) containerProvider);
        }
        for (ContainerProvider containerProvider: getContainers()) {
            ContainerInfo info = configurationFactory.createContainerInfo(containerProvider.getContainerDefinition());
            assembler.createContainer(info);
        }

        //
        // Done
        //
        starting = false;
        logger.debug("startup.ready");

        List<AbstractApplication> applicationsToDeploy = new ArrayList<AbstractApplication>(this.applicationsToDeploy);
        this.applicationsToDeploy.clear();
        for (AbstractApplication application : applicationsToDeploy) {
            application.deployApplication();
        }
    }

    public void deployApplication(AbstractApplication application) throws OpenEJBException {
        if (isStarting() || !isStarted()) {
            applicationsToDeploy.add(application);
        } else {
            application.deployApplication();
        }
    }

    public void printContainerSystem() {
        ContainerSystem containerSystem = SystemInstance.get().getComponent(ContainerSystem.class);
        if (logger.isDebugEnabled()) {
            //
            // Log Containers
            //
            logger.debug("startup.debugContainers", containerSystem.containers().length);
            if (containerSystem.containers().length > 0) {
                logger.debug("startup.debugContainersType");
                for (Container container : containerSystem.containers()) {
                    String entry = "   ";
                    switch (container.getContainerType()) {
                        case BMP_ENTITY:
                            entry += "BMP ENTITY  ";
                            break;
                        case CMP_ENTITY:
                            entry += "CMP ENTITY  ";
                            break;
                        case STATEFUL:
                            entry += "STATEFUL    ";
                            break;
                        case STATELESS:
                            entry += "STATELESS   ";
                            break;
                        case MESSAGE_DRIVEN:
                            entry += "MESSAGE     ";
                            break;
                    }
                    entry += container.getContainerID();
                    logger.debug("startup.debugEntry", entry);
                }
            }

            //
            // Log Deployments
            //
            logger.debug("startup.debugDeployments", containerSystem.deployments().length);
            if (containerSystem.deployments().length > 0) {
                logger.debug("startup.debugDeploymentsType");
                for (DeploymentInfo deployment : containerSystem.deployments()) {
                    String entry = "   ";
                    switch (deployment.getComponentType()) {
                        case BMP_ENTITY:
                            entry += "BMP_ENTITY  ";
                            break;
                        case CMP_ENTITY:
                            entry += "CMP_ENTITY  ";
                            break;
                        case STATEFUL:
                            entry += "STATEFUL    ";
                            break;
                        case STATELESS:
                            entry += "STATELESS   ";
                            break;
                        case SINGLETON:
                            entry += "SINGLETON   ";
                            break;
                        case MESSAGE_DRIVEN:
                            entry += "MESSAGE     ";
                            break;
                    }
                    entry += deployment.getDeploymentID();
                    logger.debug("startup.debugEntry", entry);
                }
            }
        }
    }

    private <T> T getBeanForType(ApplicationContext applicationContext, Class<T> type) throws OpenEJBException {
        String[] names = applicationContext.getBeanNamesForType(type);
        if (names.length == 0) {
            return null;
        }
        if (names.length > 1) {
            throw new OpenEJBException("Multiple " + type.getSimpleName() + " beans in application context: " + Arrays.toString(names));
        }

        String name = names[0];
        importedResourceIds.add(name);
        return (T) applicationContext.getBean(name);
    }

    private boolean isImportableType(Class type, Class factoryType) {
        return !type.isAnnotationPresent(Exported.class) &&
                !BeanPostProcessor.class.isAssignableFrom(type) &&
                !BeanFactoryPostProcessor.class.isAssignableFrom(type) &&
                (factoryType == null || !factoryType.isAnnotationPresent(Exported.class));
    }

    private <T extends ServiceInfo> T initPassthrough(T info, String serviceType, Object instance) {
        return initPassthrough("Spring Supplied�" + serviceType, info, serviceType, instance);
    }

    private <T extends ServiceInfo> T initPassthrough(String id, T info, String serviceType, Object instance) {
        info.id = id;
        info.service = serviceType;
        info.types = getTypes(instance.getClass());
        PassthroughFactory.add(info, instance);
        return info;
    }

    private List<String> getTypes(Class type) {
        LinkedHashSet<String> types = new LinkedHashSet<String>();
        addTypes(type, types);
        return new ArrayList<String>(types);
    }

    private void addTypes(Class clazz, LinkedHashSet<String> types) {
        if (clazz == null || Object.class.equals(clazz) || Serializable.class.equals(clazz)) {
            return;
        }
        if (types.add(clazz.getName())) {
            addTypes(clazz.getSuperclass(), types);
            for (Class intf : clazz.getInterfaces()) {
                addTypes(intf, types);
            }
        }
    }
}
TOP

Related Classes of org.apache.openejb.spring.OpenEJB

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.